//FaceCat-TypeScript
//Shanghai JuanJuanMao Information Technology Co., Ltd 
/*
* 坐标结构
*/
class FCPoint {
    // 构造函数
    constructor(ix, iy) {
        this.x = ix;
        this.y = iy;
    }
}
/*
* 大小结构
*/
class FCSize {
    // 构造函数
    constructor(icx, icy) {
        this.cx = icx;
        this.cy = icy;
    }
}
/*
* 矩形结构
*/
class FCRect {
    // 构造函数
    constructor(ileft, itop, iright, ibottom) {
        this.left = ileft;
        this.top = itop;
        this.right = iright;
        this.bottom = ibottom;
    }
}
/*
* 边距信息
*/
class FCPadding {
    // 构造函数
    constructor(ileft, itop, iright, ibottom) {
        this.left = ileft;
        this.top = itop;
        this.right = iright;
        this.bottom = ibottom;
    }
}
/*
* 转换颜色
*/
function convertColor(inColor) {
    if (inColor.indexOf("rgba(") != -1) {
        let inStrs = inColor.replace("rgba(", "").replace(")", "");
        let strs = inStrs.split(',');
        if (strs.length >= 4) {
            let a = Number(strs[3]);
            a /= 255;
            return "rgba(" + strs[0] + "," + strs[1] + "," + strs[2] + "," + a + ")";
        }
    }
    return inColor;
}
/*
* 绘图结构
*/
class FCPaint {
    constructor() {
        this.cancelClick = false; //是否退出点击
        this.canvas = null; //视图
        this.context = null; //上下文
        this.defaultUIStyle = "light"; //默认样式
        this.dragBeginPoint = new FCPoint(0, 0); //拖动开始时的触摸位置
        this.dragBeginRect = new FCRect(0, 0, 0, 0); //拖动开始时的区域
        this.draggingView = null; //正被拖动的控件
        this.editMode = 1; //编辑框的模式
        this.editingTextBox = null; //正在编辑的文本框
        this.firstTouch = false;
        this.focusedView = null; //焦点视图
        this.isDoubleClick = false; //是否双击
        this.isMobile = false;
        this.isPath = false; //是否路径
        this.lastClickTime = 0; //上次点击时间
        this.moveTo = false;
        this.offsetX = 0.0; //横向偏移
        this.offsetY = 0.0; //纵向偏移
        this.ratio = 1; //缩放比例
        this.resizeColumnState = 0.0; //改变列宽度的状态
        this.resizeColumnBeginWidth = 0.0; //改变列宽度的起始值
        this.resizeColumnIndex = -1; //改变列宽度的索引
        this.scaleFactorX = 1.0; //横向缩放比例
        this.scaleFactorY = 1.0; //纵向缩放比例
        this.secondTouch = false;
        this.systemFont = "Arial"; //系统字体
        this.textBox = null; //原生文本框
        this.touchDownPoint = new FCPoint(0, 0);
        this.touchFirstPoint = new FCPoint(0, 0);
        this.touchSecondPoint = new FCPoint(0, 0);
        this.touchDownView = null; //鼠标按下的视图
        this.touchMoveView = null; //鼠标移动的视图
        this.views = [];
        this.onClickGridCell = null; //点击单元格的回调
        this.onClickGridColumn = null; //点击列的回调
        this.onClickTreeNode = null; //点击树节点的回调
        this.onCalculateChartMaxMin = null; //计算最大最小值的回调
        this.onInvalidate = null;
        this.onInvalidateView = null;
        this.onPaint = null; //重绘回调
        this.onPaintBorder = null; //重绘边线回调
        this.onPaintGridCell = null; //绘制单元格的回调
        this.onPaintGridColumn = null; //绘制表格列的回调
        this.onPaintTreeNode = null; //绘制树节点的回调
        this.onPaintChartScale = null; //绘制坐标轴回调
        this.onPaintChartHScale = null; //绘制坐标轴回调
        this.onPaintChartStock = null; //绘制图表回调
        this.onPaintChartPlot = null; //绘制画线回调
        this.onPaintChartCrossLine = null; //绘制十字线回调
        this.onPaintCalendarDayButton = null;
        this.onPaintCalendarMonthButton = null;
        this.onPaintCalendarYearButton = null;
        this.onPaintCalendarHeadDiv = null;
        this.onRenderViews = null;
        this.onUpdateView = null; //更新布局的回调
        this.onContainsPoint = null; //是否包含坐标
        this.onMouseDown = null; //鼠标按下事件回调
        this.onMouseMove = null; //鼠标移动事件回调
        this.onMouseUp = null; //鼠标抬起事件回调
        this.onMouseWheel = null; //鼠标滚轮事件回调
        this.onTouchBegin = null; //触摸开始事件回调
        this.onTouchMove = null; //触摸移动事件回调
        this.onTouchEnd = null; //触摸结束事件回调
        this.onMouseEnter = null; //鼠标进入事件回调
        this.onMouseLeave = null; //鼠标离开事件回调
        this.onClick = null; //点击事件回调
        this.onKeyDown = null; //键盘按下事件
        this.onKeyUp = null; //键盘抬起事件
    }
    /*
    * 添加线
    * x1:横坐标1
    * y1:纵坐标1
    * x2:横坐标2
    * y2:纵坐标2
    */
    addLine(x1, y1, x2, y2) {
        if (!this.moveTo) {
            this.moveTo = true;
            this.context.moveTo(Math.round((x1 + this.offsetX) * this.scaleFactorX), Math.round((y1 + this.offsetY) * this.scaleFactorY));
        }
        this.context.lineTo(Math.round((x2 + this.offsetX) * this.scaleFactorX), Math.round((y2 + this.offsetY) * this.scaleFactorY));
    }
    /*
    * 开始路径
    */
    beginPath() {
        this.context.beginPath();
        this.isPath = true;
    }
    /*
    * 开始绘图
    * rect:区域
    */
    beginPaint(rect) {
        if (!this.context) {
            this.context = this.canvas.getContext("2d");
        }
        this.moveTo = false;
        this.offsetX = 0;
        this.offsetY = 0;
    }
    /*
    * 闭合路径
    */
    closeFigure() {
        this.context.closePath();
    }
    /*
    * 关闭路径
    */
    closePath() {
        this.moveTo = false;
    }
    /*
    * 绘制线
    * color:颜色
    * width:宽度
    * style:样式
    * x1:横坐标1
    * y1:纵坐标1
    * x2:横坐标2
    * y2:纵坐标2
    */
    drawLine(color, width, style, x1, y1, x2, y2) {
        width = Math.min(this.scaleFactorX, this.scaleFactorY) * width;
        this.context.beginPath();
        this.context.strokeStyle = convertColor(color);
        if (this.context.lineWidth < 1) {
            this.context.lineWidth = 1;
        }
        if (style) {
            this.context.setLineDash(style);
        }
        this.context.moveTo(Math.round((x1 + this.offsetX) * this.scaleFactorX), Math.round((y1 + this.offsetY) * this.scaleFactorY));
        this.context.lineTo(Math.round((x2 + this.offsetX) * this.scaleFactorX), Math.round((y2 + this.offsetY) * this.scaleFactorY));
        this.context.stroke();
        if (style) {
            this.context.setLineDash([]);
        }
    }
    /*
    * 绘制路径
    * color:颜色
    * width:宽度
    * style:样式
    */
    drawPath(color, width, style) {
        width = Math.min(this.scaleFactorX, this.scaleFactorY) * width;
        if (style) {
            this.context.setLineDash(style);
        }
        this.context.strokeStyle = convertColor(color);
        if (this.context.lineWidth < 1) {
            this.context.lineWidth = 1;
        }
        this.context.stroke();
        if (style) {
            this.context.setLineDash([]);
        }
    }
    /*
    * 绘制连续线条
    * color:颜色
    * width:宽度
    * style:样式
    */
    drawPolyline(color, width, style, apt) {
        if (apt.length > 1) {
            width = Math.min(this.scaleFactorX, this.scaleFactorY) * width;
            if (style) {
                this.context.setLineDash(style);
            }
            this.context.strokeStyle = convertColor(color);
            if (this.context.lineWidth < 1) {
                this.context.lineWidth = 1;
            }
            this.context.beginPath();
            for (let i = 0; i < apt.length; i++) {
                let x = apt[i].x;
                let y = apt[i].y;
                x = x + this.offsetX;
                y = y + this.offsetY;
                if (this.scaleFactorX != 1 || this.scaleFactorY != 1) {
                    x = this.scaleFactorX * x;
                    y = this.scaleFactorY * y;
                }
                if (i == 0) {
                    this.context.moveTo(Math.round(x), Math.round(y));
                }
                else {
                    this.context.lineTo(Math.round(x), Math.round(y));
                }
            }
            this.context.stroke();
            if (style) {
                this.context.setLineDash([]);
            }
        }
        else if (apt.length == 1) {
            this.drawLine(color, width, style, apt[0].x, apt[0].y, apt[0].x, apt[0].y);
        }
    }
    /*
    * 绘制多边形
    * color:颜色
    * width:宽度
    * style:样式
    */
    drawPolygon(color, width, style, apt) {
        if (apt.length > 1) {
            width = Math.min(this.scaleFactorX, this.scaleFactorY) * width;
            if (style) {
                this.context.setLineDash(style);
            }
            this.context.strokeStyle = convertColor(color);
            if (this.context.lineWidth < 1) {
                this.context.lineWidth = 1;
            }
            this.context.beginPath();
            for (let i = 0; i < apt.length; i++) {
                let x = apt[i].x;
                let y = apt[i].y;
                x = x + this.offsetX;
                y = y + this.offsetY;
                if (this.scaleFactorX != 1 || this.scaleFactorY != 1) {
                    x = this.scaleFactorX * x;
                    y = this.scaleFactorY * y;
                }
                if (i == 0) {
                    this.context.moveTo(Math.round(x), Math.round(y));
                }
                else {
                    this.context.lineTo(Math.round(x), Math.round(y));
                }
            }
            this.context.closePath();
            this.context.stroke();
            if (style) {
                this.context.setLineDash([]);
            }
        }
    }
    /*
    * 绘制图片
    * left:左侧坐标
    * top:上方坐标
    * right:右侧坐标
    * bottom:下方坐标
    */
    drawImage(image, left, top, right, bottom) {
        let w = right - left;
        let h = bottom - top;
        this.context.drawImage(image, Math.round((left + this.offsetX) * this.scaleFactorX), Math.round((top + this.offsetY) * this.scaleFactorY), Math.round(w * this.scaleFactorX), Math.round(h * this.scaleFactorY));
    }
    /*
    * 绘制矩形
    * color:颜色
    * width:宽度
    * style:样式
    * left:左侧坐标
    * top:上方坐标
    * right:右侧坐标
    * bottom:下方坐标
    */
    drawRect(color, width, style, left, top, right, bottom) {
        width = Math.min(this.scaleFactorX, this.scaleFactorY) * width;
        let w = right - left;
        let h = bottom - top;
        if (style) {
            this.context.setLineDash(style);
        }
        this.context.strokeStyle = convertColor(color);
        if (this.context.lineWidth < 1) {
            this.context.lineWidth = 1;
        }
        this.context.strokeRect(Math.round((left + this.offsetX) * this.scaleFactorX), Math.round((top + this.offsetY) * this.scaleFactorY), Math.round(w * this.scaleFactorX), Math.round(h * this.scaleFactorY));
        if (style) {
            this.context.setLineDash([]);
        }
    }
    /*
    * 绘制椭圆
    * color:颜色
    * width:宽度
    * style:样式
    * left:左侧坐标
    * top:上方坐标
    * right:右侧坐标
    * bottom:下方坐标
    */
    drawEllipse(color, width, style, left, top, right, bottom) {
        width = Math.min(this.scaleFactorX, this.scaleFactorY) * width;
        let w = right - left;
        let h = bottom - top;
        this.context.beginPath();
        if (this.context.ellipse) {
            this.context.ellipse(((left + (right - left) / 2) + this.offsetX) * this.scaleFactorX, ((top + (bottom - top) / 2) + this.offsetY) * this.scaleFactorY, (w / 2) * this.scaleFactorX, (h / 2) * this.scaleFactorY, 0, 0, Math.PI * 2);
        }
        if (style) {
            this.context.setLineDash(style);
        }
        this.context.strokeStyle = convertColor(color);
        if (this.context.lineWidth < 1) {
            this.context.lineWidth = 1;
        }
        this.context.stroke();
        if (style) {
            this.context.setLineDash([]);
        }
    }
    /*
    * 绘制圆角矩形
    * color:颜色
    * left:左侧坐标
    * top:上方坐标
    * right:右侧坐标
    * bottom:下方坐标
    * cornerRadius:圆角度数
    */
    drawRoundRect(color, width, style, left, top, right, bottom, cornerRadius) {
        if (cornerRadius > 0) {
            width = Math.min(this.scaleFactorX, this.scaleFactorY) * width;
            if (style) {
                this.context.setLineDash(style);
            }
            this.context.strokeStyle = convertColor(color);
            if (this.context.lineWidth < 1) {
                this.context.lineWidth = 1;
            }
            let w = Math.round((right - left) * this.scaleFactorX);
            let h = Math.round((bottom - top) * this.scaleFactorY);
            let x = (left + this.offsetX) * this.scaleFactorX;
            let y = (top + this.offsetY) * this.scaleFactorY;
            let corner = cornerRadius * Math.min(this.scaleFactorX, this.scaleFactorY);
            this.context.beginPath();
            this.context.moveTo(x + corner, y);
            this.context.arcTo(x + w, y, x + w, y + h, corner);
            this.context.arcTo(x + w, y + h, x, y + h, corner);
            this.context.arcTo(x, y + h, x, y, corner);
            this.context.arcTo(x, y, x + corner, y, corner);
            this.context.stroke();
            if (style) {
                this.context.setLineDash([]);
            }
        }
        else {
            this.drawRect(color, width, style, left, top, right, bottom);
        }
    }
    /*
    * 绘制文字
    * text:文字
    * color:颜色
    * font:字体
    * x:横坐标
    * y:纵坐标
    */
    drawText(text, color, font, x, y) {
        if (text && text.length != 0 && font) {
            let strs = font.split(',');
            let fontFamily = strs[0];
            if (fontFamily == "Default") {
                fontFamily = this.systemFont;
            }
            let sFont = parseInt(strs[1]) + "px " + fontFamily;
            if (this.scaleFactorX != 1 || this.scaleFactorY != 1) {
                sFont = Math.floor((this.scaleFactorX + this.scaleFactorY) / 2.0 * Math.floor(Number(strs[1]))) + "px " + fontFamily;
            }
            for (let i = 2; i < strs.length; i++) {
                let iStr = strs[i].toLowerCase();
                if (iStr == "bold" || iStr == "italic") {
                    sFont = iStr + " " + sFont;
                }
            }
            this.context.font = sFont;
            this.context.fillStyle = convertColor(color);
            this.context.textAlign = 'left';
            this.context.textBaseline = 'top';
            this.context.fillText(text, Math.round((x + this.offsetX) * this.scaleFactorX), Math.round((y + this.offsetY) * this.scaleFactorY));
        }
    }
    /*
    * 结束绘图
    */
    endPaint() {
    }
    /*
    * 填充路径
    * color:颜色
    */
    fillPath(color) {
        this.context.fillStyle = convertColor(color);
        this.context.fill();
    }
    /*
    * 填充多边形
    * color:颜色
    * width:宽度
    * style:样式
    */
    fillPolygon(color, apt) {
        if (apt.length > 1) {
            this.context.beginPath();
            for (let i = 0; i < apt.length; i++) {
                let x = apt[i].x;
                let y = apt[i].y;
                x = x + this.offsetX;
                y = y + this.offsetY;
                if (this.scaleFactorX != 1 || this.scaleFactorY != 1) {
                    x = this.scaleFactorX * x;
                    y = this.scaleFactorY * y;
                }
                if (i == 0) {
                    this.context.moveTo(Math.round(x), Math.round(y));
                }
                else {
                    this.context.lineTo(Math.round(x), Math.round(y));
                }
            }
            this.context.fillStyle = convertColor(color);
            this.context.closePath();
            this.context.fill();
        }
    }
    /*
    * 填充矩形
    * color:颜色
    * left:左侧坐标
    * top:上方坐标
    * right:右侧坐标
    * bottom:下方坐标
    */
    fillRect(color, left, top, right, bottom) {
        let w = right - left;
        let h = bottom - top;
        this.context.fillStyle = convertColor(color);
        this.context.fillRect(Math.round((left + this.offsetX) * this.scaleFactorX), Math.round((top + this.offsetY) * this.scaleFactorY), Math.round(w * this.scaleFactorX), Math.round(h * this.scaleFactorY));
    }
    /*
    * 填充圆角矩形
    * color:颜色
    * left:左侧坐标
    * top:上方坐标
    * right:右侧坐标
    * bottom:下方坐标
    * cornerRadius:圆角度数
    */
    fillRoundRect(color, left, top, right, bottom, cornerRadius) {
        if (cornerRadius > 0) {
            let w = Math.round((right - left) * this.scaleFactorX);
            let h = Math.round((bottom - top) * this.scaleFactorY);
            let x = (left + this.offsetX) * this.scaleFactorX;
            let y = (top + this.offsetY) * this.scaleFactorY;
            let corner = cornerRadius * Math.min(this.scaleFactorX, this.scaleFactorY);
            this.context.beginPath();
            this.context.moveTo(x + corner, y);
            this.context.arcTo(x + w, y, x + w, y + h, corner);
            this.context.arcTo(x + w, y + h, x, y + h, corner);
            this.context.arcTo(x, y + h, x, y, corner);
            this.context.arcTo(x, y, x + corner, y, corner);
            this.context.fillStyle = convertColor(color);
            this.context.fill();
        }
        else {
            this.fillRect(color, left, top, right, bottom);
        }
    }
    /*
    * 填充椭圆
    * color:颜色
    * left:左侧坐标
    * top:上方坐标
    * right:右侧坐标
    * bottom:下方坐标
    */
    fillEllipse(color, left, top, right, bottom) {
        let w = right - left;
        let h = bottom - top;
        this.context.beginPath();
        if (this.context.ellipse) {
            this.context.ellipse(((left + (right - left) / 2) + this.offsetX) * this.scaleFactorX, ((top + (bottom - top) / 2) + this.offsetY) * this.scaleFactorY, (w / 2) * this.scaleFactorX, (h / 2) * this.scaleFactorY, 0, 0, Math.PI * 2);
        }
        this.context.fillStyle = convertColor(color);
        this.context.fill();
    }
    /*
    * 裁剪
    * left:左侧坐标
    * top:上方坐标
    * right:右侧坐标
    * bottom:下方坐标
    */
    setClip(left, top, right, bottom) {
        let w = right - left;
        let h = bottom - top;
        this.context.beginPath();
        this.context.rect(Math.round((left + this.offsetX) * this.scaleFactorX), Math.round((top + this.offsetY) * this.scaleFactorY), Math.round(w * this.scaleFactorX), Math.round(h * this.scaleFactorY));
        this.context.clip();
    }
    /*
    * 设置偏移量
    * offsetX:横向偏移
    * offsetY:纵向偏移
    */
    setOffset(x, y) {
        this.offsetX = x;
        this.offsetY = y;
    }
    /*
    * 获取字体大小
    * text:文字
    * font:字体
    */
    textSize(text, font) {
        if (text && text.length != 0 && font) {
            let strs = font.split(',');
            let fontFamily = strs[0];
            if (fontFamily == "Default") {
                fontFamily = this.systemFont;
            }
            let rate = (this.scaleFactorX + this.scaleFactorY) / 2.0;
            let sFont = Math.floor(Number(strs[1]) * rate) + "px " + fontFamily;
            for (let i = 2; i < strs.length; i++) {
                let iStr = strs[i].toLowerCase();
                if (iStr == "bold" || iStr == "italic") {
                    sFont = iStr + " " + sFont;
                }
            }
            this.context.font = sFont;
            let metrics = this.context.measureText(text);
            let actualHeight = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;
            if (!actualHeight || actualHeight <= 0) {
                actualHeight = Number(strs[1]);
            }
            let tSize = new FCSize(metrics.width / rate, actualHeight / rate);
            return tSize;
        }
        else {
            return new FCSize(0, 0);
        }
    }
    /*
    * 保存状态
    */
    save() {
        this.context.save();
    }
    /*
    * 恢复状态
    */
    restore() {
        this.context.restore();
    }
    /*
    * 绘制文字
    * text:文字
    * color:颜色
    * font:字体
    * left:左侧坐标
    * top:上方坐标
    * right:右侧坐标
    * bottom:下方坐标
    */
    drawTextAutoEllipsis(text, color, font, left, top, right, bottom) {
        if (text && text.length != 0) {
            let tSize = this.textSize(text, font);
            if (tSize.cx < right - left) {
                this.drawText(text, color, font, left, top);
            }
            else {
                if (tSize.cx > 0) {
                    let subLen = 3;
                    while (true) {
                        let newLen = text.length - subLen;
                        if (newLen > 0) {
                            let newText = text.substring(0, newLen) + "...";
                            tSize = this.textSize(newText, font);
                            if (tSize.cx < right - left) {
                                this.drawText(newText, color, font, left, top);
                                break;
                            }
                            else {
                                subLen += 3;
                            }
                        }
                        else {
                            break;
                        }
                    }
                }
            }
        }
    }
}
/*
* 基础视图
*/
class FCView {
    // 构造函数
    constructor() {
        this.allowDrag = false; //是否允许拖动
        this.allowResize = false; //是否可以拖动改变大小
        this.align = "left"; //横向布局
        this.allowDragScroll = true; //是否允许拖动滚动
        this.allowPreviewsEvent = false; //是否允许预处理事件
        this.backColor = "rgb(255,255,255)"; //背景色
        this.borderColor = "rgb(150,150,150)"; //边线色
        this.borderWidth = 1; //边线宽度
        this.clipRect = new FCRect(0, 0, 0, 0); //裁剪区域
        this.cornerRadius = 0; //圆角
        this.cursor = ""; //光标
        this.downScrollHButton = false; //是否按下横向滚动条
        this.downScrollVButton = false; //是否按下纵向滚动条
        this.displayOffset = true; //是否显示偏移量
        this.dock = "none"; //悬浮状态
        this.enabled = true; //是否可用
        this.exAttributes = new Map(); //额外属性
        this.font = "Default,12"; //字体
        this.hoveredColor = null; //鼠标悬停时的颜色
        this.hoverScrollHButton = false; //是否悬停横向滚动条
        this.hoverScrollVButton = false; //是否悬停纵向滚动条
        this.hScrollIsVisible = false; //横向滚动是否显示
        this.input = null; //输入框
        this.location = new FCPoint(0, 0); //坐标
        this.margin = new FCPadding(0, 0, 0, 0); //外边距
        this.maximumSize = new FCSize(0, 0); //最大大小
        this.padding = new FCPadding(0, 0, 0, 0); //内边距
        this.paint = null; //绘图对象
        this.parent = null; //父视图
        this.pushedColor = "rgb(100,100,100)"; //鼠标按下时的颜色
        this.resizePoint = -1; //调整尺寸的点
        this.scrollV = 0.0; //纵向滚动
        this.scrollH = 0.0; //横向滚动
        this.scrollSize = 8.0; //滚动条的大小
        this.showHScrollBar = false; //是否显示横向滚动条
        this.showVScrollBar = false; //是否显示横向滚动条
        this.scrollBarColor = "rgb(200,200,200)"; //滚动条的颜色
        this.scrollBarHoveredColor = "rgb(42,138,195)"; //滚动条悬停的颜色
        this.size = new FCSize(0, 0); //大小
        this.startScrollH = 0.0; //开始滚动的值
        this.startScrollV = 0.0; //结束滚动的值
        this.startPoint = new FCPoint(0, 0); //起始点
        this.startRect = new FCRect(0, 0, 0, 0); //移动开始时的视图矩形
        this.tabIndex = 0; //Tab索引
        this.tabStop = false; //是否支持Tab
        this.text = ""; //文字
        this.textColor = "rgb(0,0,0)"; //前景色
        this.topMost = false; //是否置顶
        this.touchDownTime = 0; //鼠标按下的时间
        this.viewName = ""; //名称
        this.visible = true; //可见性
        this.verticalAlign = "top"; //纵向布局
        this.viewType = "none"; //类型
        this.vScrollIsVisible = false; //纵向滚动是否显示
        this.views = [];
        this.onPaint = null; //重绘回调
        this.onPaintBorder = null; //重绘边线回调
        this.onClick = null; //点击方法
        this.onMouseDown = null; //鼠标按下
        this.onMouseMove = null; //鼠标移动
        this.onMouseWheel = null; //鼠标滚动
        this.onMouseUp = null; //鼠标抬起
        this.onTouchBegin = null; //触摸开始
        this.onTouchMove = null; //触摸移动
        this.onTouchEnd = null; //触摸结束
        this.onKeyDown = null; //键盘按下
        this.onKeyUp = null; //键盘抬起
        this.onMouseEnter = null;
        this.onMouseLeave = null;
    }
}
/*
* 按钮
*/
class FCButton extends FCView {
    // 构造函数
    constructor() {
        super();
        this.viewType = "button";
        this.hoveredColor = "rgb(150,150,150)";
        this.pushedColor = "rgb(200,200,200)";
    }
}
/*
* 标签
*/
class FCLabel extends FCView {
    // 构造函数
    constructor() {
        super();
        this.viewType = "label";
        this.borderColor = null;
    }
}
/*
* 文本框
*/
class FCTextBox extends FCView {
    // 构造函数
    constructor() {
        super();
        this.viewType = "textbox";
    }
}
/*
* 数值输入框
*/
class FCSpin extends FCView {
    // 构造函数
    constructor() {
        super();
        this.viewType = "spin";
    }
}
/*
* 图层
*/
class FCDiv extends FCView {
    // 构造函数
    constructor() {
        super();
        this.viewType = "div";
    }
}
/*
* 页
*/
class FCTabPage extends FCView {
    // 构造函数
    constructor() {
        super();
        this.headerButton = null; //页头的按钮
        this.viewType = "tabpage";
        this.visible = false;
    }
}
/*
* 多页夹
*/
class FCTabView extends FCView {
    // 构造函数
    constructor() {
        super();
        this.animationSpeed = 20; //动画速度
        this.layout = "top"; //布局方式
        this.tabPages = []; //页夹集合
        this.underLineColor = null; //下划线的颜色
        this.underLineSize = 0; //下划线的宽度
        this.underPoint = new FCPoint(0, 0); //下划点
        this.useAnimation = false; //是否使用动画
        this.viewType = "tabview";
    }
}
/*
* 复选按钮
*/
class FCCheckBox extends FCView {
    // 构造函数
    constructor() {
        super();
        this.buttonSize = new FCSize(16, 16); //按钮的大小
        this.checked = false; //是否选中
        this.viewType = "checkbox";
    }
}
/*
 * 多布局图层
 */
class FCLayoutDiv extends FCDiv {
    // 构造函数
    constructor() {
        super();
        this.autoWrap = false; //是否自动换行
        this.layoutStyle = "lefttoright"; //分割方式
        this.viewType = "layout";
    }
}
/*
* 分割图层
*/
class FCSplitLayoutDiv extends FCView {
    // 构造函数
    constructor() {
        super();
        this.firstView = null; //第一个视图
        this.layoutStyle = "lefttoright"; //分割方式
        this.oldSize = new FCSize(0, 0); //上次的尺寸
        this.splitMode = "absolutesize"; //分割模式 percentsize百分比或absolutesize绝对值
        this.splitPercent = -1; //分割百分比
        this.secondView = null; //第二个视图
        this.splitter = null; //分割线
        this.viewType = "split";
    }
}
/*
* 单选按钮
*/
class FCRadioButton extends FCView {
    // 构造函数
    constructor() {
        super();
        this.buttonSize = new FCSize(16, 16); //按钮的大小
        this.checked = false; //是否选中
        this.groupName = ""; //组别
        this.viewType = "radiobutton";
    }
}
/*
* 表格列
*/
class FCGridColumn {
    constructor() {
        this.allowSort = true; //是否允许排序
        this.allowResize = false; //是否允许改变大小
        this.backColor = "rgb(200,200,200)"; //背景色
        this.borderColor = "rgb(150,150,150)"; //边线颜色
        this.bounds = new FCRect(0, 0, 0, 0); //区域
        this.cellAlign = "left"; //left:居左 center:居中 right:居右
        this.colName = ""; //名称
        this.colType = ""; //类型 string:字符串 double:浮点型 int:整型 bool: 布尔型
        this.font = "Default,14"; //字体
        this.frozen = false; //是否冻结
        this.index = -1; //索引
        this.text = ""; //文字
        this.textColor = "rgb(50,50,50)"; //文字颜色
        this.shapeType = ""; //类型
        this.sort = "none"; //排序模式
        this.width = 120; //宽度
        this.widthStr = ""; //宽度字符串
        this.visible = true; //是否可见
    }
}
/*
* 表格单元格
*/
class FCGridCell {
    constructor() {
        this.backColor = "rgb(255,255,255)"; //背景色
        this.borderColor = "rgb(150,150,150)"; //边线色
        this.colSpan = 1; //列距
        this.column = null; //所在列
        this.digit = -1; //保留小数的位数
        this.font = "Default,14"; //字体
        this.row = null; //所在行
        this.rowSpan = 1; //行距
        this.textColor = "rgb(0,0,0)"; //前景色
        this.value = ""; //值
        this.view = null; //包含的视图
    }
}
/*
* 表格行
*/
class FCGridRow {
    constructor() {
        this.cells = []; //单元格
        this.index = -1;
        this.key = ""; //排序键值
        this.selected = false; //是否选中
        this.visible = true; //是否可见
    }
}
/*
* 表格
*/
class FCGrid extends FCView {
    // 构造函数
    constructor() {
        super();
        this.columns = []; //所有的列
        this.headerHeight = 30; //头部高度
        this.rowHeight = 30; //行高
        this.rows = []; //包含的所有行
        this.selectedRowColor = "rgb(125,125,125)"; //选中行的颜色
        this.onClickGridCell = null; //点击单元格的回调
        this.onClickGridColumn = null; //点击列的回调
        this.onPaintGridCell = null; //绘制单元格的回调
        this.onPaintGridColumn = null; //绘制表格列的回调
        this.viewType = "grid";
        this.showHScrollBar = true;
        this.showVScrollBar = true;
    }
}
/*
* 树的列
*/
class FCTreeColumn {
    constructor() {
        this.bounds = new FCRect(0, 0, 0, 0); //区域
        this.index = -1; //索引
        this.visible = true; //是否可见
        this.width = 120; //宽度
        this.widthStr = ""; //宽度字符串
    }
}
/*
* 树的行
*/
class FCTreeRow {
    constructor() {
        this.cells = []; //单元格
        this.index = -1; //索引
        this.selected = false; //是否选中
        this.visible = true; //是否可见
    }
}
/*
* 树节点
*/
class FCTreeNode {
    constructor() {
        this.allowCollapsed = true; //是否允许折叠
        this.backColor = "rgb(255,255,255)"; //背景色
        this.checked = false; //是否选中
        this.childNodes = []; //子节点
        this.collapsed = false; //是否折叠
        this.column = null; //所有的列
        this.font = "Default,14"; //字体
        this.indent = 0; //缩进
        this.parentNode = null;
        this.row = null; //包含的所有行
        this.textColor = "rgb(0,0,0)"; //前景色
        this.value = ""; //值   
    }
}
/*
* 树
*/
class FCTree extends FCView {
    // 构造函数
    constructor() {
        super();
        this.checkBoxWidth = 25; //复选框占用的宽度
        this.columns = []; //所有的列
        this.collapsedWidth = 25; //折叠按钮占用的宽度
        this.childNodes = []; //子节点
        this.headerHeight = 0; //头部高度
        this.indent = 20; //缩进
        this.rowHeight = 30; //行高
        this.rows = []; //包含的所有行
        this.selectedRowColor = "rgb(125,125,125)"; //选中行的颜色
        this.showCheckBox = false; //是否显示复选框
        this.onClickTreeNode = null; //点击树节点的回调
        this.onPaintTreeNode = null; //绘制树节点的回调
        this.viewType = "tree";
        this.showHScrollBar = true;
        this.showVScrollBar = true;
    }
}
/*
* 证券数据结构
*/
class SecurityData {
    constructor() {
        this.amount = 0.0; //成交额
        this.close = 0.0; //收盘价
        this.date = 0.0; //日期，为1970年到现在的秒
        this.high = 0.0; //最高价
        this.low = 0.0; //最低价
        this.open = 0.0; //开盘价
        this.volume = 0.0; //成交额
    }
}
/*
* 基础图形
*/
class BaseShape {
    constructor() {
        this.color = null; //颜色
        this.color2 = null; //颜色2
        this.datas = []; //第一组数据
        this.datas2 = []; //第二组数据
        this.divIndex = 0; //所在层
        this.leftOrRight = true; //依附于左轴或右轴
        this.lineWidth = 1; //线的宽度
        this.shapeType = "line"; //类型
        this.shapeName = ""; //名称
        this.showHideDatas = []; //控制显示隐藏的数据
        this.style = ""; //样式
        this.text = ""; //显示的文字
        this.title = ""; //第一个标题
        this.title2 = ""; //第二个标题
        this.value = 0; //显示文字的值
    }
}
/*
* 画线工具结构
*/
class FCPlot {
    constructor() {
        this.key1 = 0.0; //第一个键
        this.key2 = 0.0; //第二个键
        this.key3 = 0.0; //第三个键
        this.lineColor = "rgb(0,0,0)"; //线的颜色
        this.lineWidth = 1; //线的宽度
        this.plotType = "Line"; //线的类型
        this.pointColor = "rgba(0,0,0,120)"; //线的颜色
        this.startKey1 = 0.0; //移动前第一个键
        this.startValue1 = 0.0; //移动前第一个值
        this.startKey2 = 0.0; //移动前第二个键
        this.startValue2 = 0.0; //移动前第二个值
        this.startKey3 = 0.0; //移动前第三个键
        this.startValue3 = 0.0; //移动前第三个值
        this.value1 = 0.0; //第一个值
        this.value2 = 0.0; //第二个值
        this.value3 = 0.0; //第三个值
    }
}
/*
* 图表
*/
class FCChart extends FCView {
    // 构造函数
    constructor() {
        super();
        this.autoFillHScale = false; //是否填充满X轴
        this.allowDragChartDiv = false; //是否允许拖拽图层
        this.candleDistance = 0; //蜡烛线的距离
        this.candleMax = 0; //蜡烛线的最大值
        this.candleMin = 0; //蜡烛线的最小值
        this.candleMaxRight = 0; //蜡烛线的右轴最大值
        this.candleMinRight = 0; //蜡烛线的右轴最小值
        this.crossTipColor = "rgb(50,50,50)"; //十字线标识的颜色
        this.crossLineColor = "rgb(100,100,100)"; //十字线的颜色
        this.candleDigit = 2; //图表层保留小数的位数
        this.candleDivPercent = 0.5; //图表层的占比
        this.candlePaddingTop = 30; //图表层的上边距
        this.candlePaddingBottom = 30; //图表层的下边距
        this.crossStopIndex = -1; //鼠标停留位置
        this.cycle = "day"; //周期
        this.data = []; //子节点
        this.downColor = "rgb(15,193,118)"; //下跌颜色
        this.firstVisibleIndex = -1; //起始可见的索引
        this.gridColor = "rgb(150,150,150)"; //网格颜色
        this.hScalePixel = 11; //蜡烛线的宽度
        this.hScaleHeight = 30; //X轴的高度
        this.hScaleTextDistance = 10; //X轴的文字间隔
        this.hScaleFormat = ""; //X轴的格式化字符，例如YYYY-mm-dd HH:MM:SS
        this.indMax = 0; //指标层的最大值
        this.indMin = 0; //指标的最小值
        this.indMax2 = 0; //指标层2的最大值
        this.indMin2 = 0; //指标层2的最小值
        this.indMaxRight = 0; //指标层的右轴最大值
        this.indMinRight = 0; //指标层的右轴最小值
        this.indMax2Right = 0; //指标层2的右轴最大值
        this.indMin2Right = 0; //指标层2的右轴最小值
        this.indDigit = 2; //指标层保留小数的位数
        this.indDigit2 = 2; //指标层2保留小数的位数
        this.indDivPercent = 0.3; //指标层的占比
        this.indDivPercent2 = 0.0; //指标层2的占比
        this.indPaddingTop = 20; //指标层的上边距
        this.indPaddingBottom = 20; //指标层的下边距
        this.indPaddingTop2 = 20; //指标层2的上边距
        this.indPaddingBottom2 = 20; //指标层2的下边距
        this.indicatorColors = []; //扩展图形
        this.leftVScaleWidth = 80; //左轴宽度
        this.lastVisibleIndex = -1; //结束可见的索引
        this.lastRecordIsVisible = true; //最后记录是否可见
        this.lastVisibleKey = 0; //最后可见的主键
        this.lastValidIndex = -1; //最后有效数据索引
        this.lineWidthChart = 1;
        this.mainIndicator = ""; //主图指标
        this.magnitude = 1; //成交量的比例
        this.midColor = "none"; //中间色
        this.offsetX = 0; //横向绘图偏移
        this.plots = []; //画线
        this.plotPointSizeChart = 5; //画线的选中点大小
        this.rightVScaleWidth = 0; //右轴宽度
        this.rightSpace = 0; //右侧空间
        this.scaleColor = "rgb(100,100,100)"; //刻度的颜色
        this.showIndicator = ""; //显示指标
        this.showIndicator2 = ""; //显示指标2
        this.showCrossLine = false; //是否显示十字线
        this.selectPlotPoint = -1; //选中画线的点
        this.startMovePlot = false; //选中画线
        this.selectShape = ""; //选中的图形
        this.selectShapeEx = ""; //选中的图形信息
        this.shapes = []; //扩展图形
        this.sPlot = null; //选中的线条
        this.targetOldX = 0; //缩小时旧的位置1
        this.targetOldX2 = 0; //放大时旧的位置2
        this.touchPosition = new FCPoint(0, 0); //鼠标坐标
        this.trendColor = "rgb(0,0,0)"; //分时线颜色
        this.volMax = 0; //成交量层的最大值
        this.volMin = 0; //成交量层的最小值
        this.volMaxRight = 0; //成交量层的右轴最大值
        this.volMinRight = 0; //成交量层的右轴最小值
        this.volDigit = 0; //成交量层保留小数的位数
        this.volDivPercent = 0.2; //成交量层的占比
        this.volPaddingTop = 20; //成交量层的上边距
        this.volPaddingBottom = 0; //成交量层的下边距
        this.vScaleDistance = 35; //纵轴的间隔
        this.vScaleType = "standard"; //纵轴的类型 log10代表指数坐标
        this.upColor = "rgb(219,68,83)"; //上涨颜色
        this.kChart = 0.0;
        this.bChart = 0.0;
        this.oXChart = 0.0;
        this.oYChart = 0.0;
        this.rChart = 0.0;
        this.gridStepChart = 0.0; //网格计算临时变量
        this.gridDigitChart = 0.0; //网格计算临时变量
        this.candleStyle = "rect";
        this.barStyle = "rect";
        this.firstOpen = 0.0;
        this.hScaleTextColor = "none"; //横轴的文字颜色
        this.vScaleTextColor = "none"; //纵轴的文字颜色
        //拖动滚动的缓存
        this.firstIndexCacheChart = -1;
        this.firstTouchIndexCacheChart = -1;
        this.firstTouchPointCacheChart = new FCPoint(0, 0);
        this.lastIndexCacheChart = -1;
        this.secondTouchIndexCacheChart = -1;
        this.secondTouchPointCacheChart = new FCPoint(0, 0);
        this.firstPaddingTop = 0.0;
        this.firtstPaddingBottom = 0.0;
        this.touchDownPointChart = new FCPoint(0, 0);
        this.addingPlotChart = "";
        this.x4Chart = 0.0;
        this.y4Chart = 0.0;
        this.nHighChart = 0.0;
        this.nLowChart = 0.0;
        this.xChart = 0.0;
        this.yChart = 0.0;
        this.wChart = 0.0;
        this.hChart = 0.0;
        this.upSubValue = 0.0;
        this.downSubValue = 0.0;
        this.allema12 = [];
        this.allema26 = [];
        this.alldifarr = [];
        this.alldeaarr = [];
        this.allmacdarr = [];
        this.bollUp = [];
        this.bollDown = [];
        this.bollMid = [];
        this.bias1 = [];
        this.bias2 = [];
        this.bias3 = [];
        this.kdjK = [];
        this.kdjD = [];
        this.kdjJ = [];
        this.rsi1 = [];
        this.rsi2 = [];
        this.rsi3 = [];
        this.roc = [];
        this.rocMa = [];
        this.wr1 = [];
        this.wr2 = [];
        this.cci = [];
        this.bbi = [];
        this.trix = [];
        this.trixMa = [];
        this.dma1 = [];
        this.dma2 = [];
        this.ma5 = [];
        this.ma10 = [];
        this.ma20 = [];
        this.ma30 = [];
        this.ma120 = [];
        this.ma250 = [];
        this.closeArr = [];
        this.onCalculateChartMaxMin = null; //计算最大最小值的回调
        this.onPaintChartScale = null; //绘制坐标轴回调
        this.onPaintChartHScale = null; //绘制坐标轴回调
        this.onPaintChartStock = null; //绘制图表回调
        this.onPaintChartPlot = null; //绘制画线回调
        this.onPaintChartCrossLine = null; //绘制十字线回调
        this.viewType = "chart";
        this.showHScrollBar = true;
        this.showVScrollBar = true;
        this.indicatorColors.push("rgb(100,100,100)");
        this.indicatorColors.push("rgb(206,147,27)");
        this.indicatorColors.push("rgb(150,0,150)");
        this.indicatorColors.push("rgb(255,0,0)");
        this.indicatorColors.push("rgb(0,150,150)");
        this.indicatorColors.push("rgb(0,150,0)");
        this.indicatorColors.push("rgb(59,174,218)");
        this.indicatorColors.push("rgb(50,50,50)");
    }
}
/*
* 月层
*/
class MonthDiv {
    constructor() {
        this.aDirection = 0; //动画的方向
        this.aTick = 0; //动画当前帧数
        this.aTotalTick = 40; //动画总帧数
        this.month = 0; //月份
        this.monthButtons = []; //月的按钮
        this.monthButtonsAm = []; //动画日期的集合
        this.year = 0; //年份
    }
}
/*
* 年层
*/
class YearDiv {
    constructor() {
        this.aDirection = 0; //动画的方向
        this.aTick = 0; //动画当前帧数
        this.aTotalTick = 40; //动画总帧数
        this.startYear = 0; //开始年份
        this.yearButtons = []; //年的按钮
        this.yearButtonsAm = []; //动画日期的集合
    }
}
/*
* 头部层
*/
class HeadDiv {
    constructor() {
        this.arrowColor = "rgb(150,150,150)"; //箭头颜色
        this.backColor = "rgb(255,255,255)"; //箭头颜色
        this.bounds = new FCRect(0, 0, 0, 0); //显示区域
        this.textColor = "rgb(0,0,0)"; //文字颜色
        this.titleFont = "Default,20"; //标题字体
        this.weekFont = "Default,14"; //星期字体
    }
}
/*
* 时间层
*/
class TimeDiv {
    constructor() {
        this.bounds = new FCRect(0, 0, 0, 0); //显示区域
    }
}
/*
* 年的结构
*/
class CYear {
    constructor() {
        this.months = new Map(); //月的集合
        this.year = 0; //年
    }
}
/*
* 月的结构
*/
class CMonth {
    constructor() {
        this.days = new Map(); //日的集合
        this.month = 0; //月
        this.year = 0; //年
    }
}
/*
* 日的结构
*/
class CDay {
    constructor() {
        this.day = 0; //日
        this.month = 0; //月
        this.year = 0; //年
    }
}
/*
* 日历
*/
class FCCalendar extends FCView {
    // 构造函数
    constructor() {
        super();
        this.dayDiv = new DayDiv(); //日层
        this.headDiv = new HeadDiv(); //头部层
        this.mode = "day"; //模式
        this.monthDiv = new MonthDiv(); //月层
        this.selectedDay = new CDay(); //选中日
        this.timeDiv = new TimeDiv(); //时间层
        this.useAnimation = false; //是否使用动画
        this.yearDiv = new YearDiv(); //年层
        this.years = new Map(); //日历
        this.onPaintCalendarDayButton = null; //绘制日历的日按钮回调
        this.onPaintCalendarMonthButton = null; //绘制日历的月按钮回调
        this.onPaintCalendarYearButton = null; //绘制日历的年按钮回调
        this.onPaintCalendarHeadDiv = null; //绘制日历头部回调
        this.viewType = "calendar";
    }
}
/*
* 日的按钮
*/
class DayButton {
    constructor() {
        this.backColor = null; //背景颜色
        this.borderColor = "rgb(150,150,150)"; //文字颜色
        this.bounds = new FCRect(0, 0, 0, 0); //显示区域
        this.day = null; //日期
        this.font = "Default,16"; //字体
        this.inThisMonth = false; //是否在本月
        this.selected = false; //是否被选中
        this.textColor = "rgb(0,0,0)"; //文字颜色
        this.textColor2 = "rgb(50,50,50)"; //第二个文字颜色
        this.visible = true; //是否可见 
    }
}
/*
* 月的按钮
*/
class MonthButton {
    constructor() {
        this.bounds = new FCRect(0, 0, 0, 0); //显示区域
        this.backColor = null; //背景颜色
        this.borderColor = "rgb(150,150,150)"; //文字颜色
        this.font = "Default,16"; //字体
        this.month = 0; //月
        this.textColor = "rgb(0,0,0)"; //文字颜色
        this.visible = true; //是否可见
        this.year = 0; //年
    }
}
/*
* 年的按钮
*/
class YearButton {
    constructor() {
        this.backColor = null; //背景颜色
        this.borderColor = "rgb(150,150,150)"; //文字颜色
        this.bounds = new FCRect(0, 0, 0, 0); //显示区域
        this.font = "Default,16"; //字体
        this.textColor = "rgb(0,0,0)"; //文字颜色
        this.visible = true; //是否可见
        this.year = 0; //年
    }
}
/*
* 日期层
*/
class DayDiv {
    constructor() {
        this.aClickRowFrom = 0; //点击时的上月的行
        this.aClickRowTo = 0; //点击时的当月的行
        this.aDirection = 0; //动画的方向
        this.aTick = 0; //动画当前帧数
        this.aTotalTick = 40; //动画总帧数
        this.dayButtons = []; //日期的集合
        this.dayButtonsAm = []; //动画日期的集合
    }
}
/*
* 菜单
*/
class FCMenu extends FCLayoutDiv {
    // 构造函数
    constructor() {
        super();
        this.autoSize = true; //是否自动适应尺寸
        this.comboBox = null; //所在的下拉菜单
        this.items = []; //菜单项
        this.popup = true; //是否弹出
        this.viewType = "menu";
        this.size = new FCSize(100, 100);
        this.showHScrollBar = true;
        this.showVScrollBar = true;
        this.visible = false;
        this.layoutStyle = "toptobottom";
        this.autoWrap = false;
        this.maximumSize = new FCSize(100, 300);
        this.allowPreviewsEvent = true;
    }
}
/*
* 菜单项
*/
class FCMenuItem extends FCView {
    // 构造函数
    constructor() {
        super();
        this.checked = false; //是否选中
        this.dropDownMenu = null; //下拉菜单
        this.items = []; //菜单项
        this.parentMenu = null; //所在菜单
        this.parentItem = null; //父菜单项
        this.value = ""; //值
        this.viewType = "menuitem";
        this.hoveredColor = "rgb(150,150,150)";
        this.pushedColor = "rgb(200,200,200)";
        this.size = new FCSize(100, 25);
    }
}
/*
* 下拉选择
*/
class FCComboBox extends FCView {
    // 构造函数
    constructor() {
        super();
        this.dropDownMenu = null; //下拉菜单 
        this.selectedIndex = -1; //选中索引
        this.viewType = "combobox";
    }
}
/*
* 添加顶层视图
* view 视图
* paint 绘图对象
*/
function addView(view, paint) {
    view.paint = paint;
    paint.views.push(view);
}
/*
* 添加到父视图
* view 视图
* parent 父视图
*/
function addViewToParent(view, parent) {
    view.paint = parent.paint;
    if (!parent.views) {
        parent.views = new Array();
    }
    parent.views.push(view);
    view.parent = parent;
}
/*
* 清除输入框
*/
function clearViewInputs(views) {
    for (let i = 0; i < views.length; i++) {
        let view = views[i];
        if (view.input) {
            document.body.removeChild(view.input);
            view.input = null;
        }
        clearViewInputs(view.views);
    }
}
;
/*
* 清除视图
* paint:绘图对象
*/
function clearViews(paint) {
    clearViewInputs(paint.views);
    paint.views = [];
}
;
/*
* 移除顶层视图
* view 视图
* paint 绘图对象
*/
function removeView(view, paint) {
    if (paint.views) {
        for (let i = 0; i < paint.views.length; i++) {
            if (paint.views[i] == view) {
                paint.views.splice(i, 1);
                let removeViews = new Array();
                removeViews.push(view);
                clearViewInputs(removeViews);
                break;
            }
        }
    }
}
/*
* 从父视图中移除
* view 视图
* parent 父视图
*/
function removeViewFromParent(view, parent) {
    if (parent.views) {
        for (let i = 0; i < parent.views.length; i++) {
            if (parent.views[i] == view) {
                parent.views.splice(i, 1);
                let removeViews = new Array();
                removeViews.push(view);
                clearViewInputs(removeViews);
                break;
            }
        }
    }
}
/*
* 获取绝对位置X
* view:视图
*/
function clientX(view) {
    if (view) {
        let cLeft = view.location.x;
        if (view.parent) {
            if (view.parent.displayOffset && view.parent.scrollH) {
                return cLeft + clientX(view.parent) - view.parent.scrollH;
            }
            else {
                return cLeft + clientX(view.parent);
            }
        }
        else {
            return cLeft;
        }
    }
    else {
        return 0;
    }
}
/*
* 获取绝对位置Y
* view:视图
*/
function clientY(view) {
    if (view) {
        let cTop = view.location.y;
        if (view.parent) {
            if (view.parent.displayOffset && view.parent.scrollV) {
                return cTop + clientY(view.parent) - view.parent.scrollV;
                ;
            }
            else {
                return cTop + clientY(view.parent);
            }
        }
        else {
            return cTop;
        }
    }
    else {
        return 0;
    }
}
/*
* 是否包含坐标
* view:视图
* mp:坐标
*/
function containsPoint(view, mp) {
    if (isViewEnabled(view)) {
        let clx = clientX(view);
        let cly = clientY(view);
        let size = view.size;
        let cp = new FCPoint(mp.x - clx, mp.y - cly);
        if (cp.x >= 0 && cp.x <= size.cx &&
            cp.y >= 0 && cp.y <= size.cy) {
            return true;
        }
        else {
            return false;
        }
    }
    else {
        return false;
    }
}
/*
* 查找有预处理事件的父视图
* view:视图
*/
function findPreviewsEventParent(view) {
    if (!view.allowPreviewsEvent && view.parent) {
        if (view.parent.allowPreviewsEvent) {
            return view.parent;
        }
        else {
            return findPreviewsEventParent(view.parent);
        }
    }
    else {
        return null;
    }
}
/*
* 根据名称查找视图
* name:名称
* views:视图集合
*/
function findViewByName(name, views) {
    let size = views.length;
    for (let i = 0; i < size; i++) {
        let view = views[i];
        if (view.viewName == name) {
            return view;
        }
        else {
            if (view.views) {
                let subView = findViewByName(name, view.views);
                if (subView) {
                    return subView;
                }
            }
        }
    }
    return null;
}
/*
* 根据坐标查找视图
* mp:坐标
* views:视图集合
*/
function findView(mp, views) {
    let size = views.length;
    for (let i = size - 1; i >= 0; i--) {
        let view = views[i];
        if (view.visible && view.topMost) {
            let hasPoint = false;
            if (view.paint != null && view.paint.onContainsPoint) {
                hasPoint = view.paint.onContainsPoint(view, mp);
            }
            else {
                hasPoint = containsPoint(view, mp);
            }
            if (hasPoint) {
                if (view.vScrollIsVisible && view.scrollSize) {
                    let clx = clientX(view);
                    if (mp.x >= clx + view.size.cx - view.scrollSize) {
                        return view;
                    }
                }
                if (view.hScrollIsVisible && view.scrollSize) {
                    let cly = clientY(view);
                    if (mp.y >= cly + view.size.cy - view.scrollSize) {
                        return view;
                    }
                }
                if (view.views) {
                    let subView = findView(mp, view.views);
                    if (subView) {
                        return subView;
                    }
                }
                return view;
            }
        }
    }
    for (let i = size - 1; i >= 0; i--) {
        let view = views[i];
        if (view.visible && !view.topMost) {
            let hasPoint = false;
            if (view.paint != null && view.paint.onContainsPoint) {
                hasPoint = view.paint.onContainsPoint(view, mp);
            }
            else {
                hasPoint = containsPoint(view, mp);
            }
            if (hasPoint) {
                if (view.vScrollIsVisible && view.scrollSize) {
                    let clx = clientX(view);
                    if (mp.x >= clx + view.size.cx - view.scrollSize) {
                        return view;
                    }
                }
                if (view.hScrollIsVisible && view.scrollSize) {
                    let cly = clientY(view);
                    if (mp.y >= cly + view.size.cy - view.scrollSize) {
                        return view;
                    }
                }
                if (view.views) {
                    let subView = findView(mp, view.views);
                    if (subView) {
                        return subView;
                    }
                }
                return view;
            }
        }
    }
    return null;
}
/*
* 获取点击位置
* evt:事件
* canvas:图层
* ratio:比例
*/
function getMousePostion(evt, canvas, paint) {
    let style = window.getComputedStyle(canvas, null);
    //宽高
    let cssWidth = Number(style["width"].replace("px", ""));
    let cssHeight = Number(style["height"].replace("px", ""));
    //各个方向的边框长度
    /*let borderLeft = Number(style["border-left-width"]);
    let borderTop = Number(style["border-top-width"]);
    let paddingLeft = Number(style["padding-left"]);
    let paddingTop = Number(style["padding-top"]);*/
    let borderLeft = 0;
    let borderTop = 0;
    let paddingLeft = 0;
    let paddingTop = 0;
    let scaleX = canvas.width / cssWidth; // 水平方向的缩放因子
    let scaleY = canvas.height / cssHeight; // 垂直方向的缩放因子
    let x = evt.clientX;
    let y = evt.clientY;
    let rect = canvas.getBoundingClientRect();
    x -= (rect.left + borderLeft + paddingLeft); // 去除 borderLeft paddingLeft 后的坐标
    y -= (rect.top + borderTop + paddingTop); // 去除 borderLeft paddingLeft 后的坐标
    x *= scaleX; // 修正水平方向的坐标
    y *= scaleY; // 修正垂直方向的坐标
    x /= paint.ratio;
    y /= paint.ratio;
    if (paint) {
        x /= paint.scaleFactorX;
        y /= paint.scaleFactorY;
    }
    return { x, y };
}
/*
* 获取点击位置
* evt:事件
* canvas:图层
* ratio:比例
*/
function getTouchPostion(evt, canvas, index, paint) {
    let style = window.getComputedStyle(canvas, null);
    //宽高
    let cssWidth = Number(style["width"].replace("px", ""));
    let cssHeight = Number(style["height"].replace("px", ""));
    //各个方向的边框长度
    /*let borderLeft = Number(style["border-left-width"]);
    let borderTop = Number(style["border-top-width"]);
    let paddingLeft = Number(style["padding-left"]);
    let paddingTop = Number(style["padding-top"]);*/
    let borderLeft = 0;
    let borderTop = 0;
    let paddingLeft = 0;
    let paddingTop = 0;
    let scaleX = canvas.width / cssWidth; // 水平方向的缩放因子
    let scaleY = canvas.height / cssHeight; // 垂直方向的缩放因子
    let x = evt.touches[index].clientX;
    let y = evt.touches[index].clientY;
    let rect = canvas.getBoundingClientRect();
    x -= (rect.left + borderLeft + paddingLeft); // 去除 borderLeft paddingLeft 后的坐标
    y -= (rect.top + borderTop + paddingTop); // 去除 borderLeft paddingLeft 后的坐标
    x *= scaleX; // 修正水平方向的坐标
    y *= scaleY; // 修正垂直方向的坐标
    x /= paint.ratio;
    y /= paint.ratio;
    if (paint) {
        x /= paint.scaleFactorX;
        y /= paint.scaleFactorY;
    }
    return { x, y };
}
/*
* 是否重绘时可见
* view:视图
*/
function isPaintVisible(view) {
    if (view.visible) {
        if (view.parent) {
            if (view.parent.visible) {
                return isPaintVisible(view.parent);
            }
            else {
                return false;
            }
        }
        else {
            return true;
        }
    }
    else {
        return false;
    }
}
/*
* 是否重绘时可见
* view:视图
*/
function isViewEnabled(view) {
    if (view.enabled) {
        if (view.parent) {
            if (view.parent.enabled) {
                return isViewEnabled(view.parent);
            }
            else {
                return false;
            }
        }
        else {
            return true;
        }
    }
    else {
        return false;
    }
}
/*
* 获取区域的交集
*/
function getIntersectRect(lpDestRect, lpSrc1Rect, lpSrc2Rect) {
    lpDestRect.left = Math.max(lpSrc1Rect.left, lpSrc2Rect.left);
    lpDestRect.right = Math.min(lpSrc1Rect.right, lpSrc2Rect.right);
    lpDestRect.top = Math.max(lpSrc1Rect.top, lpSrc2Rect.top);
    lpDestRect.bottom = Math.min(lpSrc1Rect.bottom, lpSrc2Rect.bottom);
    if (lpDestRect.right > lpDestRect.left && lpDestRect.bottom > lpDestRect.top) {
        return 1;
    }
    else {
        lpDestRect.left = 0;
        lpDestRect.right = 0;
        lpDestRect.top = 0;
        lpDestRect.bottom = 0;
        return 0;
    }
}
/*
* 重绘视图
* views:视图集合
* paint:绘图对象
* rect:区域
*/
function renderViews(views, paint, rect) {
    let viewsSize = views.length;
    for (let i = 0; i < viewsSize; i++) {
        let view = views[i];
        if (!rect) {
            if (view.views) {
                let subViewsSize = view.views.length;
                if (subViewsSize > 0) {
                    renderViews(view.views, paint, null);
                }
            }
            view.clipRect = null;
            continue;
        }
        if (!view.topMost && isPaintVisible(view)) {
            let clx = clientX(view);
            let cly = clientY(view);
            let drawRect = new FCRect(0, 0, view.size.cx, view.size.cy);
            let clipRect = new FCRect(clx, cly, clx + view.size.cx, cly + view.size.cy);
            let destRect = new FCRect(0, 0, 0, 0);
            if (getIntersectRect(destRect, rect, clipRect) > 0) {
                paint.save();
                paint.setOffset(0, 0);
                paint.setClip(destRect.left, destRect.top, destRect.right, destRect.bottom);
                view.clipRect = destRect;
                paint.setOffset(clx, cly);
                if (paint.onPaint) {
                    paint.onPaint(view, paint, drawRect);
                }
                else {
                    onPaintDefault(view, paint, drawRect);
                }
                if (view.views) {
                    let subViewsSize = view.views.length;
                    if (subViewsSize > 0) {
                        renderViews(view.views, paint, destRect);
                    }
                }
                paint.setOffset(clx, cly);
                if (paint.onPaintBorder) {
                    paint.onPaintBorder(view, paint, drawRect);
                }
                else {
                    onPaintBorderDefault(view, paint, drawRect);
                }
                paint.restore();
            }
            else {
                if (view.views) {
                    let subViewsSize = view.views.length;
                    if (subViewsSize > 0) {
                        renderViews(view.views, paint, null);
                    }
                }
                view.clipRect = null;
            }
        }
    }
    for (let i = 0; i < viewsSize; i++) {
        let view = views[i];
        if (!rect) {
            continue;
        }
        if (view.topMost && isPaintVisible(view)) {
            let clx = clientX(view);
            let cly = clientY(view);
            let drawRect = new FCRect(0, 0, view.size.cx, view.size.cy);
            let clipRect = new FCRect(clx, cly, clx + view.size.cx, cly + view.size.cy);
            let destRect = new FCRect(0, 0, 0, 0);
            if (getIntersectRect(destRect, rect, clipRect) > 0) {
                paint.save();
                paint.setOffset(0, 0);
                view.clipRect = destRect;
                paint.setClip(destRect.left, destRect.top, destRect.right, destRect.bottom);
                paint.setOffset(clx, cly);
                if (paint.onPaint) {
                    paint.onPaint(view, paint, drawRect);
                }
                else {
                    onPaintDefault(view, paint, drawRect);
                }
                if (view.views) {
                    let subViewsSize = view.views.length;
                    if (subViewsSize > 0) {
                        renderViews(view.views, paint, destRect);
                    }
                }
                paint.setOffset(clx, cly);
                if (paint.onPaintBorder) {
                    paint.onPaintBorder(view, paint, drawRect);
                }
                else {
                    onPaintBorderDefault(view, paint, drawRect);
                }
                paint.restore();
            }
            else {
                if (view.views) {
                    let subViewsSize = view.views.length;
                    if (subViewsSize > 0) {
                        renderViews(view.views, paint, null);
                    }
                }
                view.clipRect = null;
            }
        }
    }
}
/*
* 刷新输入框
*/
function invalidateEdit(paint) {
    if (paint.textBox && paint.editingTextBox && paint.textBox.style.display == "block") {
        let canvas = paint.canvas;
        let rect = canvas.getBoundingClientRect();
        let newTop = rect.top + document.documentElement.scrollTop;
        let newLeft = rect.left + document.documentElement.scrollLeft;
        let view = paint.editingTextBox;
        let clx = clientX(view);
        let cly = clientY(view);
        let relativeRect = new FCRect(newLeft + clx * paint.scaleFactorX, newTop + cly * paint.scaleFactorY, newLeft + (clx + view.size.cx) * paint.scaleFactorX, newTop + (cly + view.size.cy) * paint.scaleFactorY);
        paint.textBox.style.left = relativeRect.left + "px";
        paint.textBox.style.top = relativeRect.top + "px";
        paint.textBox.style.width = (relativeRect.right - relativeRect.left) + "px";
        paint.textBox.style.height = (relativeRect.bottom - relativeRect.top) + "px";
    }
}
;
/*
* 全局刷新方法
* paint:绘图对象
*/
function invalidate(paint) {
    let drawViews = paint.views;
    if (paint.onInvalidate) {
        paint.onInvalidate(paint);
    }
    else {
        paint.beginPaint(null);
        let drawRect = new FCRect(0, 0, (paint.canvas.width / paint.ratio / paint.scaleFactorX), (paint.canvas.height / paint.ratio / paint.scaleFactorY));
        if (paint.onRenderViews) {
            paint.onRenderViews(drawViews, paint, drawRect);
        }
        else {
            renderViews(drawViews, paint, drawRect);
        }
        paint.endPaint();
        if (paint.editMode == 0) {
            showOrHideInput(drawViews);
        }
        else {
            invalidateEdit(paint);
        }
    }
}
/*
* 刷新视图方法
* view:视图
*/
function invalidateView(view) {
    let paint = view.paint;
    if (paint.onInvalidateView) {
        paint.onInvalidateView(view);
    }
    else {
        if (isPaintVisible(view)) {
            let clX = clientX(view) - 1;
            let clY = clientY(view) - 1;
            let drawViews = paint.views;
            paint.beginPaint(null);
            let drawRect = new FCRect(clX, clY, clX + view.size.cx + 1, clY + view.size.cy + 1);
            if (paint.onRenderViews) {
                paint.onRenderViews(drawViews, paint, drawRect);
            }
            else {
                renderViews(drawViews, paint, drawRect);
            }
            paint.endPaint();
            if (paint.editMode == 0) {
                showOrHideInput(drawViews);
            }
            else {
                invalidateEdit(paint);
            }
        }
    }
}
/*
* 显示或隐藏输入框
*/
function showOrHideInput(views) {
    for (let i = 0; i < views.length; i++) {
        let view = views[i];
        let paintVisible = isPaintVisible(view);
        if (view.views) {
            showOrHideInput(view.views);
        }
        if (view.input) {
            let clipRect = view.clipRect;
            if (clipRect) {
                let canvas = view.paint.canvas;
                let rect = canvas.getBoundingClientRect();
                let newTop = rect.top + document.documentElement.scrollTop;
                let newLeft = rect.left + document.documentElement.scrollLeft;
                let relativeRect = new FCRect(newLeft + clipRect.left * view.paint.scaleFactorX, newTop + clipRect.top * view.paint.scaleFactorY, newLeft + clipRect.right * view.paint.scaleFactorX, newTop + clipRect.bottom * view.paint.scaleFactorY);
                view.input.style.left = relativeRect.left + "px";
                view.input.style.top = relativeRect.top + "px";
                view.input.style.width = (relativeRect.right - relativeRect.left) + "px";
                view.input.style.height = (relativeRect.bottom - relativeRect.top) + "px";
                view.input.style.backgroundColor = convertColor(view.backColor);
                view.input.style.border = "1px solid " + convertColor(view.borderColor);
                view.input.style.color = convertColor(view.textColor);
                if (paintVisible) {
                    view.input.style.display = "block";
                }
                else {
                    view.input.style.display = "none";
                }
            }
        }
    }
}
;
/*
* 更新悬浮状态
* views:视图集合
*/
function updateViewDefault(views) {
    for (let i = 0; i < views.length; i++) {
        let view = views[i];
        if (view.exAttributes.has("leftstr")) {
            let pWidth = view.paint.canvas.width / view.paint.ratio / view.paint.scaleFactorX;
            if (view.parent) {
                pWidth = view.parent.size.cx;
            }
            let newStr = view.exAttributes.get("leftstr");
            newStr = newStr.replace("%", "");
            view.location.x = Number(newStr) * pWidth / 100;
        }
        if (view.exAttributes.has("topstr")) {
            let pHeight = view.paint.canvas.height / view.paint.ratio / view.paint.scaleFactorY;
            if (view.parent) {
                pHeight = view.parent.size.cy;
            }
            let newStr = view.exAttributes.get("topstr");
            newStr = newStr.replace("%", "");
            view.location.y = Number(newStr) * pHeight / 100;
        }
        if (view.exAttributes.has("widthstr")) {
            let pWidth = view.paint.canvas.width / view.paint.ratio / view.paint.scaleFactorX;
            if (view.parent) {
                pWidth = view.parent.size.cx;
            }
            let newStr = view.exAttributes.get("widthstr");
            newStr = newStr.replace("%", "");
            view.size.cx = Number(newStr) * pWidth / 100;
        }
        if (view.exAttributes.has("heightstr")) {
            let pHeight = view.paint.canvas.height / view.paint.ratio / view.paint.scaleFactorY;
            if (view.parent) {
                pHeight = view.parent.size.cy;
            }
            let newStr = view.exAttributes.get("heightstr");
            newStr = newStr.replace("%", "");
            view.size.cy = Number(newStr) * pHeight / 100;
        }
        if (view.parent && view.parent.viewType != "split") {
            let margin = view.margin;
            let padding = view.parent.padding;
            if (view.dock == "fill") {
                view.location = new FCPoint(margin.left + padding.left, margin.top + padding.top);
                let vcx = view.parent.size.cx - margin.left - padding.left - margin.right - padding.right;
                if (vcx < 0) {
                    vcx = 0;
                }
                let vcy = view.parent.size.cy - margin.top - padding.top - margin.bottom - padding.bottom;
                if (vcy < 0) {
                    vcy = 0;
                }
                view.size = new FCSize(vcx, vcy);
            }
            else if (view.dock == "left") {
                view.location = new FCPoint(margin.left + padding.left, margin.top + padding.top);
                let vcy = view.parent.size.cy - margin.top - padding.top - margin.bottom - padding.bottom;
                if (vcy < 0) {
                    vcy = 0;
                }
                view.size = new FCSize(view.size.cx, vcy);
            }
            else if (view.dock == "top") {
                view.location = new FCPoint(margin.left + padding.left, margin.top + padding.top);
                let vcx = view.parent.size.cx - margin.left - padding.left - margin.right - padding.right;
                if (vcx < 0) {
                    vcx = 0;
                }
                view.size = new FCSize(vcx, view.size.cy);
            }
            else if (view.dock == "right") {
                view.location = new FCPoint(view.parent.size.cx - view.size.cx - padding.right - margin.right, margin.top + padding.top);
                let vcy = view.parent.size.cy - margin.top - padding.top - margin.bottom - padding.bottom;
                if (vcy < 0) {
                    vcy = 0;
                }
                view.size = new FCSize(view.size.cx, vcy);
            }
            else if (view.dock == "bottom") {
                view.location = new FCPoint(margin.left + padding.left, view.parent.size.cy - view.size.cy - margin.bottom - padding.bottom);
                let vcx = view.parent.size.cx - margin.left - padding.left - margin.right - padding.right;
                if (vcx < 0) {
                    vcx = 0;
                }
                view.size = new FCSize(vcx, view.size.cy);
            }
            if (view.align == "center") {
                view.location = new FCPoint((view.parent.size.cx - view.size.cx) / 2, view.location.y);
            }
            else if (view.align == "right") {
                view.location = new FCPoint(view.parent.size.cx - view.size.cx - padding.right - margin.right, view.location.y);
            }
            if (view.verticalAlign == "middle") {
                view.location = new FCPoint(view.location.x, (view.parent.size.cy - view.size.cy) / 2);
            }
            else if (view.verticalAlign == 'bottom') {
                view.location = new FCPoint(view.location.x, view.parent.size.cy - view.size.cy - padding.bottom - margin.bottom);
            }
        }
        else if (!view.parent) {
            if (view.dock == "fill") {
                let paint = view.paint;
                view.size = new FCSize((paint.canvas.width / paint.ratio / paint.scaleFactorX), (paint.canvas.height / paint.ratio / paint.scaleFactorY));
            }
        }
        if (view.viewType == "split") {
            resetSplitLayoutDiv(view);
        }
        else if (view.viewType == "tabview") {
            updateTabLayout(view);
        }
        else if (view.viewType == "layout") {
            resetLayoutDiv(view);
        }
        else if (view.viewType == "calendar") {
            updateCalendar(view);
        }
        else if (view.viewType == "chart") {
            let chart = view;
            resetChartVisibleRecord(chart);
            checkChartLastVisibleIndex(chart);
            if (chart.onCalculateChartMaxMin) {
                chart.onCalculateChartMaxMin(chart);
            }
            else if (chart.paint.onCalculateChartMaxMin) {
                chart.paint.onCalculateChartMaxMin(chart);
            }
            else {
                calculateChartMaxMin(chart);
            }
        }
        if (view.views) {
            updateViewDefault(view.views);
        }
    }
}
/*
* 视图尺寸改变
*/
function windowResize(rect, resizePoint, nowPoint, startTouchPoint) {
    if (resizePoint == 0) {
        rect.left = rect.left + nowPoint.x - startTouchPoint.x;
        rect.top = rect.top + nowPoint.y - startTouchPoint.y;
    }
    else if (resizePoint == 1) {
        rect.left = rect.left + nowPoint.x - startTouchPoint.x;
        rect.bottom = rect.bottom + nowPoint.y - startTouchPoint.y;
    }
    else if (resizePoint == 2) {
        rect.right = rect.right + nowPoint.x - startTouchPoint.x;
        rect.top = rect.top + nowPoint.y - startTouchPoint.y;
    }
    else if (resizePoint == 3) {
        rect.right = rect.right + nowPoint.x - startTouchPoint.x;
        rect.bottom = rect.bottom + nowPoint.y - startTouchPoint.y;
    }
    else if (resizePoint == 4) {
        rect.left = rect.left + nowPoint.x - startTouchPoint.x;
    }
    else if (resizePoint == 5) {
        rect.top = rect.top + nowPoint.y - startTouchPoint.y;
    }
    else if (resizePoint == 6) {
        rect.right = rect.right + nowPoint.x - startTouchPoint.x;
    }
    else if (resizePoint == 7) {
        rect.bottom = rect.bottom + nowPoint.y - startTouchPoint.y;
    }
}
/*
* 获取调整尺寸的点
*/
function getResizeState(view, mp) {
    let bWidth = 5;
    let width = view.size.cx, height = view.size.cy;
    if (mp.x >= 0 && mp.x <= bWidth * 2 && mp.y >= 0 && mp.y <= bWidth * 2) {
        return 0;
    }
    else if (mp.x >= 0 && mp.x <= bWidth * 2 && mp.y >= height - bWidth * 2 && mp.y <= height) {
        return 1;
    }
    else if (mp.x >= width - bWidth * 2 && mp.x <= width && mp.y >= 0 && mp.y <= bWidth * 2) {
        return 2;
    }
    else if (mp.x >= width - bWidth * 2 && mp.x <= width && mp.y >= height - bWidth * 2 && mp.y <= height) {
        return 3;
    }
    else if (mp.x >= 0 && mp.x <= bWidth && mp.y >= 0 && mp.y <= height) {
        return 4;
    }
    else if (mp.x >= 0 && mp.x <= width && mp.y >= 0 && mp.y <= bWidth) {
        return 5;
    }
    else if (mp.x >= width - bWidth && mp.x <= width && mp.y >= 0 && mp.y <= height) {
        return 6;
    }
    else if (mp.x >= 0 && mp.x <= width && mp.y >= height - bWidth && mp.y <= height) {
        return 7;
    }
    else {
        return -1;
    }
}
/*
* 添加鼠标按下的方法
* canvas:图层
* callBack:回调函数
*/
function addMouseDownEvent(canvas, paint, callBack) {
    canvas.onmousedown = function (evt) {
        if (!paint.isMobile) {
            let mp = getMousePostion(evt, canvas, paint);
            paint.cancelClick = false;
            paint.touchDownPoint = mp;
            let lastFocusedView = paint.focusedView;
            paint.touchDownView = findView(mp, paint.views);
            let newClickTime = new Date().getTime();
            let clicks = 1;
            if (newClickTime - paint.lastClickTime < 250) {
                paint.isDoubleClick = true;
                paint.lastClickTime = 0;
                clicks = 2;
            }
            else {
                paint.isDoubleClick = false;
                paint.lastClickTime = newClickTime;
            }
            checkShowMenu(paint);
            if (paint.touchDownView) {
                paint.focusedView = paint.touchDownView;
                let cmp = new FCPoint(mp.x - clientX(paint.touchDownView), mp.y - clientY(paint.touchDownView));
                if (callBack) {
                    if (evt.button == 2) {
                        callBack(paint.touchDownView, cmp, 2, clicks, 0);
                    }
                    else {
                        callBack(paint.touchDownView, cmp, 1, clicks, 0);
                    }
                }
                else if (paint.onMouseDown != null && paint.touchDownView.onMouseDown == null) {
                    if (evt.button == 2) {
                        paint.onMouseDown(paint.touchDownView, cmp, 2, clicks, 0);
                    }
                    else {
                        paint.onMouseDown(paint.touchDownView, cmp, 1, clicks, 0);
                    }
                }
                else {
                    if (evt.button == 2) {
                        onMouseDownDefault(paint.touchDownView, cmp, 2, clicks, 0);
                    }
                    else {
                        onMouseDownDefault(paint.touchDownView, cmp, 1, clicks, 0);
                    }
                }
                if (paint.touchDownView.allowResize) {
                    paint.touchDownView.resizePoint = getResizeState(paint.touchDownView, cmp);
                    if (paint.touchDownView.resizePoint = -1) {
                        paint.touchDownView.startRect = new FCRect(paint.touchDownView.location.x, paint.touchDownView.location.y, paint.touchDownView.location.x + paint.touchDownView.size.cx, paint.touchDownView.location.y + paint.touchDownView.size.cy);
                    }
                }
                if (paint.editMode == 1) {
                    if (paint.focusedView.viewType == "textbox") {
                        showTextInput(paint.focusedView, lastFocusedView);
                    }
                    else {
                        hideTextInput(paint.focusedView);
                    }
                }
            }
            if (paint.editMode == 0) {
                showOrHideInput(paint.views);
            }
        }
    };
}
/*
* 添加鼠标移动的方法
* canvas:图层
* callBack:回调函数
*/
function addMouseMoveEvent(canvas, paint, callBack) {
    canvas.onmousemove = function (evt) {
        if (evt.buttons == 0) {
            paint.touchDownView = null;
        }
        if (!paint.isMobile) {
            let mp = getMousePostion(evt, canvas, paint);
            if (paint.touchDownView) {
                paint.touchMoveView = paint.touchDownView;
                let cmp = new FCPoint(mp.x - clientX(paint.touchDownView), mp.y - clientY(paint.touchDownView));
                if (callBack) {
                    callBack(paint.touchDownView, cmp, 1, 1, 0);
                }
                else if (paint.onMouseMove != null && paint.touchDownView.onMouseMove == null) {
                    paint.onMouseMove(paint.touchDownView, cmp, 1, 1, 0);
                }
                else {
                    onMouseMoveDefault(paint.touchDownView, cmp, 1, 1, 0);
                }
                if (paint.touchDownView.resizePoint != -1) {
                    let newBounds = new FCRect(paint.touchDownView.startRect.left, paint.touchDownView.startRect.top, paint.touchDownView.startRect.right, paint.touchDownView.startRect.bottom);
                    windowResize(newBounds, paint.touchDownView.resizePoint, mp, paint.touchDownPoint);
                    paint.touchDownView.location = new FCPoint(newBounds.left, newBounds.top);
                    paint.touchDownView.size = new FCSize(newBounds.right - newBounds.left, newBounds.bottom - newBounds.top);
                    if (paint.touchDownView.parent) {
                        if (paint.touchDownView.parent.paint) {
                            invalidateView(paint.touchDownView.parent);
                        }
                    }
                    else {
                        if (paint) {
                            invalidate(paint);
                        }
                    }
                }
                else if (paint.touchDownView.allowDrag) {
                    if (Math.abs(mp.x - paint.touchDownPoint.x) > 5 || Math.abs(mp.y - paint.touchDownPoint.y) > 5) {
                        paint.dragBeginRect = new FCRect(paint.touchDownView.location.x, paint.touchDownView.location.y, paint.touchDownView.location.x + paint.touchDownView.size.cx, paint.touchDownView.location.y + paint.touchDownView.size.cy);
                        paint.dragBeginPoint = new FCPoint(paint.touchDownPoint.x, paint.touchDownPoint.y);
                        paint.draggingView = paint.touchDownView;
                        paint.touchDownView = null;
                    }
                }
            }
            else if (paint.draggingView != null) {
                let offsetX = mp.x - paint.dragBeginPoint.x;
                let offsetY = mp.y - paint.dragBeginPoint.y;
                let newBounds = new FCRect(paint.dragBeginRect.left + offsetX, paint.dragBeginRect.top + offsetY, paint.dragBeginRect.right + offsetX, paint.dragBeginRect.bottom + offsetY);
                paint.draggingView.location = new FCPoint(newBounds.left, newBounds.top);
                if (paint.draggingView.parent && paint.draggingView.parent.viewType == "split") {
                    paint.draggingView.parent.splitPercent = -1;
                    resetSplitLayoutDiv(paint.draggingView.parent);
                    if (paint.onUpdateView) {
                        paint.onUpdateView(paint.draggingView.parent.views);
                    }
                    else {
                        updateViewDefault(paint.draggingView.parent.views);
                    }
                }
                if (paint.draggingView.parent) {
                    if (paint.draggingView.parent.paint) {
                        invalidateView(paint.draggingView.parent);
                    }
                }
                else {
                    if (paint) {
                        invalidate(paint);
                    }
                }
            }
            else {
                let view = findView(mp, paint.views);
                let cmp = new FCPoint(mp.x - clientX(view), mp.y - clientY(view));
                if (view) {
                    let oldMouseMoveView = paint.touchMoveView;
                    paint.touchMoveView = view;
                    if (oldMouseMoveView && oldMouseMoveView != view) {
                        invalidateView(oldMouseMoveView);
                    }
                    if (oldMouseMoveView || oldMouseMoveView != view) {
                        if (paint.canvas) {
                            paint.canvas.style.cursor = view.cursor;
                        }
                    }
                    if (callBack) {
                        callBack(view, cmp, 0, 0, 0);
                    }
                    else if (paint.onMouseMove != null && view.onMouseMove == null) {
                        paint.onMouseMove(view, cmp, 0, 0, 0);
                    }
                    else {
                        onMouseMoveDefault(view, cmp, 0, 0, 0);
                    }
                }
            }
        }
    };
}
/*
* 添加鼠标移动的方法
* canvas:图层
* callBack:回调函数
* enterCallBack:进入回调函数
* leaveCallBack:离开回调函数
*/
let addMouseMoveEvent2 = function (canvas, paint, callBack, enterCallBack, leaveCallBack) {
    canvas.onmousemove = function (evt) {
        if (evt.buttons == 0) {
            paint.touchDownView = null;
        }
        if (!paint.isMobile) {
            let mp = getMousePostion(evt, canvas, paint);
            if (paint.touchDownView) {
                paint.touchMoveView = paint.touchDownView;
                let cmp = new FCPoint(mp.x - clientX(paint.touchDownView), mp.y - clientY(paint.touchDownView));
                if (callBack) {
                    callBack(paint.touchDownView, cmp, 1, 1, 0);
                }
                else if (paint.onMouseMove != null && paint.touchDownView.onMouseMove == null) {
                    paint.onMouseMove(paint.touchDownView, cmp, 1, 1, 0);
                }
                else {
                    onMouseMoveDefault(paint.touchDownView, cmp, 1, 1, 0);
                }
                if (paint.touchDownView.resizePoint != -1) {
                    let newBounds = new FCRect(paint.touchDownView.startRect.left, paint.touchDownView.startRect.top, paint.touchDownView.startRect.right, paint.touchDownView.startRect.bottom);
                    windowResize(newBounds, paint.touchDownView.resizePoint, mp, paint.touchDownPoint);
                    paint.touchDownView.location = new FCPoint(newBounds.left, newBounds.top);
                    paint.touchDownView.size = new FCSize(newBounds.right - newBounds.left, newBounds.bottom - newBounds.top);
                    if (paint.touchDownView.parent) {
                        if (paint.touchDownView.parent.paint) {
                            invalidateView(paint.touchDownView.parent);
                        }
                    }
                    else {
                        if (paint) {
                            invalidate(paint);
                        }
                    }
                }
                else if (paint.touchDownView.allowDrag) {
                    if (Math.abs(mp.x - paint.touchDownPoint.x) > 5 || Math.abs(mp.y - paint.touchDownPoint.y) > 5) {
                        paint.dragBeginRect = new FCRect(paint.touchDownView.location.x, paint.touchDownView.location.y, paint.touchDownView.location.x + paint.touchDownView.size.cx, paint.touchDownView.location.y + paint.touchDownView.size.cy);
                        paint.dragBeginPoint = new FCPoint(paint.touchDownPoint.x, paint.touchDownPoint.y);
                        paint.draggingView = paint.touchDownView;
                        paint.touchDownView = null;
                    }
                }
            }
            else if (paint.draggingView != null) {
                let offsetX = mp.x - paint.dragBeginPoint.x;
                let offsetY = mp.y - paint.dragBeginPoint.y;
                let newBounds = new FCRect(paint.dragBeginRect.left + offsetX, paint.dragBeginRect.top + offsetY, paint.dragBeginRect.right + offsetX, paint.dragBeginRect.bottom + offsetY);
                paint.draggingView.location = new FCPoint(newBounds.left, newBounds.top);
                if (paint.draggingView.parent && paint.draggingView.parent.viewType == "split") {
                    paint.draggingView.parent.splitPercent = -1;
                    resetSplitLayoutDiv(paint.draggingView.parent);
                    if (paint.draggingView.paint.onUpdateView) {
                        paint.draggingView.paint.onUpdateView(paint.draggingView.parent.views);
                    }
                    else {
                        updateViewDefault(paint.draggingView.parent.views);
                    }
                }
                if (paint.draggingView.parent) {
                    if (paint.draggingView.parent.paint) {
                        invalidateView(paint.draggingView.parent);
                    }
                }
                else {
                    if (paint) {
                        invalidate(paint);
                    }
                }
            }
            else {
                let view = findView(mp, paint.views);
                let cmp = new FCPoint(mp.x - clientX(view), mp.y - clientY(view));
                if (view) {
                    let oldMouseMoveView = paint.touchMoveView;
                    paint.touchMoveView = view;
                    if (oldMouseMoveView && oldMouseMoveView != view) {
                        if (oldMouseMoveView.onMouseLeave != null) {
                            oldMouseMoveView.onMouseLeave(oldMouseMoveView, cmp, 0, 0, 0);
                        }
                        else if (leaveCallBack) {
                            leaveCallBack(oldMouseMoveView, cmp, 0, 0, 0);
                        }
                        else if (paint.onMouseLeave != null) {
                            paint.onMouseLeave(oldMouseMoveView, cmp, 0, 0, 0);
                        }
                        invalidateView(oldMouseMoveView);
                    }
                    if (oldMouseMoveView || oldMouseMoveView != view) {
                        if (view.onMouseEnter != null) {
                            view.onMouseEnter(view, cmp, 0, 0, 0);
                        }
                        else if (enterCallBack) {
                            enterCallBack(view, cmp, 0, 0, 0);
                        }
                        else if (paint.onMouseEnter != null) {
                            paint.onMouseEnter(view, cmp, 0, 0, 0);
                        }
                        if (paint.canvas) {
                            paint.canvas.style.cursor = view.cursor;
                        }
                    }
                    if (callBack) {
                        callBack(view, cmp, 0, 0, 0);
                    }
                    else if (paint.onMouseMove != null && view.onMouseMove == null) {
                        paint.onMouseMove(view, cmp, 0, 0, 0);
                    }
                    else {
                        onMouseMoveDefault(view, cmp, 0, 0, 0);
                    }
                }
            }
        }
    };
};
/*
* 添加鼠标滚动的方法
* canvas:图层
* callBack:回调函数
*/
function addMouseWheelEvent(canvas, paint, callBack) {
    //图层鼠标移动事件
    canvas.onwheel = function (evt) {
        if (!paint.isMobile) {
            let mp = getMousePostion(evt, canvas, paint);
            let view = findView(mp, paint.views);
            if (view) {
                let cmp = new FCPoint(mp.x - clientX(view), mp.y - clientY(view));
                let delta = evt.deltaY;
                if (callBack) {
                    callBack(view, cmp, 0, 0, delta);
                }
                else if (paint.onMouseWheel != null && view.onMouseWheel == null) {
                    paint.onMouseWheel(view, cmp, 0, 0, delta);
                }
                else {
                    onMouseWheelDefault(view, cmp, 0, 0, delta);
                }
            }
            if (view && view.allowDragScroll) {
                evt.preventDefault && evt.preventDefault();
                evt.returnValue = false;
                evt.stopPropagation && evt.stopPropagation();
            }
        }
        return false;
    };
}
;
/*
* 添加鼠标抬起的方法
* canvas:图层
* callBack:回调函数
*/
function addMouseUpEvent(canvas, paint, callBack, clickCallBack) {
    canvas.onmouseup = function (evt) {
        if (!paint.isMobile) {
            let mp = getMousePostion(evt, canvas, paint);
            if (paint.touchDownView) {
                let cmp = new FCPoint(mp.x - clientX(paint.touchDownView), mp.y - clientY(paint.touchDownView));
                let view = findView(mp, paint.views);
                let clicks = 1;
                if (paint.isDoubleClick) {
                    clicks = 2;
                }
                if (view != null && view == paint.touchDownView) {
                    if (!paint.cancelClick) {
                        if (clickCallBack) {
                            clickCallBack(paint.touchDownView, true, cmp, false, cmp, clicks);
                        }
                        else if (paint.onClick != null && paint.touchDownView.onClick == null) {
                            paint.onClick(paint.touchDownView, true, cmp, false, cmp, clicks);
                        }
                        else {
                            onClickDefault(paint.touchDownView, true, cmp, false, cmp, clicks);
                        }
                    }
                }
                if (paint.touchDownView) {
                    let touchDownView = paint.touchDownView;
                    paint.touchDownView.resizePoint = -1;
                    paint.touchDownView = null;
                    if (callBack) {
                        callBack(touchDownView, cmp, 1, clicks, 0);
                    }
                    else if (paint.onMouseUp != null && touchDownView.onMouseUp == null) {
                        paint.onMouseUp(touchDownView, cmp, 1, clicks, 0);
                    }
                    else {
                        onMouseUpDefault(touchDownView, cmp, 1, clicks, 0);
                    }
                }
            }
            paint.draggingView = null;
        }
    };
}
/*
* 添加触摸开始的方法
* canvas:图层
* callBack:回调函数
*/
function addTouchBeginEvent(canvas, paint, callBack) {
    /*
    * 触摸开始方法
    * evt: 事件参数
    */
    canvas.ontouchstart = function (evt) {
        if (paint.isMobile) {
            paint.cancelClick = false;
            let mp = getTouchPostion(evt, canvas, 0, paint);
            paint.touchDownPoint = new FCPoint(mp.x, mp.y);
            let lastFocusedView = paint.focusedView;
            paint.touchDownView = findView(mp, paint.views);
            let newClickTime = new Date().getTime();
            let clicks = 1;
            if (newClickTime - paint.lastClickTime < 250) {
                paint.isDoubleClick = true;
                paint.lastClickTime = 0;
                clicks = 2;
            }
            else {
                paint.isDoubleClick = false;
                paint.lastClickTime = newClickTime;
            }
            checkShowMenu(paint);
            if (paint.touchDownView) {
                paint.focusedView = paint.touchDownView;
                paint.firstTouch = false;
                paint.secondTouch = false;
                paint.touchFirstPoint = new FCPoint(0, 0);
                paint.touchSecondPoint = new FCPoint(0, 0);
                let clx = clientX(paint.touchDownView);
                let cly = clientY(paint.touchDownView);
                if (evt.touches.length >= 1) {
                    paint.firstTouch = true;
                    paint.touchFirstPoint = getTouchPostion(evt, canvas, 0, paint);
                    paint.touchFirstPoint.x -= clx;
                    paint.touchFirstPoint.y -= cly;
                }
                if (evt.touches.length >= 2) {
                    paint.secondTouch = true;
                    paint.touchSecondPoint = getTouchPostion(evt, canvas, 1, paint);
                    paint.touchSecondPoint.x -= clx;
                    paint.touchSecondPoint.y -= cly;
                }
                if (callBack) {
                    callBack(paint.touchDownView, paint.firstTouch, paint.touchFirstPoint, paint.secondTouch, paint.touchSecondPoint);
                }
                else if (paint.onTouchBegin != null && paint.touchDownView.onTouchBegin == null) {
                    paint.onTouchBegin(paint.touchDownView, paint.firstTouch, paint.touchFirstPoint, paint.secondTouch, paint.touchSecondPoint);
                }
                else {
                    onTouchBeginDefault(paint.touchDownView, paint.firstTouch, paint.touchFirstPoint, paint.secondTouch, paint.touchSecondPoint);
                }
                if (paint.touchDownView.allowResize) {
                    paint.touchDownView.resizePoint = getResizeState(paint.touchDownView, paint.touchFirstPoint);
                    if (paint.touchDownView.resizePoint = -1) {
                        paint.touchDownView.startRect = new FCRect(paint.touchDownView.location.x, paint.touchDownView.location.y, paint.touchDownView.location.x + paint.touchDownView.size.cx, paint.touchDownView.location.y + paint.touchDownView.size.cy);
                    }
                }
                if (paint.editMode == 1) {
                    if (paint.focusedView.viewType == "textbox") {
                        showTextInput(paint.focusedView, lastFocusedView);
                    }
                    else {
                        hideTextInput(paint.focusedView);
                    }
                }
                if (paint.editMode == 0) {
                    showOrHideInput(paint.views);
                }
            }
        }
    };
}
/*
* 添加触摸移动的方法
* canvas:图层
* callBack:回调函数
*/
function addTouchMoveEvent(canvas, paint, callBack) {
    canvas.ontouchmove = function (evt) {
        if (paint.isMobile) {
            if (paint.touchDownView) {
                paint.firstTouch = false;
                paint.secondTouch = false;
                paint.touchFirstPoint = new FCPoint(0, 0);
                paint.touchSecondPoint = new FCPoint(0, 0);
                let mp = getTouchPostion(evt, canvas, 0, paint);
                let pParent = findPreviewsEventParent(paint.focusedView);
                if (pParent && pParent.allowDragScroll && (pParent.viewType == "div" || pParent.viewType == "layout" || pParent.viewType == "menu")) {
                    paint.touchMoveView = pParent;
                    paint.focusedView = pParent;
                    paint.touchDownView = pParent;
                    let clx = clientX(paint.touchDownView);
                    let cly = clientY(paint.touchDownView);
                    if (evt.touches.length >= 1) {
                        paint.firstTouch = true;
                        paint.touchFirstPoint = getTouchPostion(evt, canvas, 0, paint);
                        paint.touchFirstPoint.x -= clx;
                        paint.touchFirstPoint.y -= cly;
                    }
                    if (evt.touches.length >= 2) {
                        paint.secondTouch = true;
                        paint.touchSecondPoint = getTouchPostion(evt, canvas, 1, paint);
                        paint.touchSecondPoint.x -= clx;
                        paint.touchSecondPoint.y -= cly;
                    }
                    touchDownDiv(pParent, paint.firstTouch, paint.touchFirstPoint, paint.secondTouch, paint.touchSecondPoint, 1);
                    touchMoveDiv(pParent, paint.firstTouch, paint.touchFirstPoint, paint.secondTouch, paint.touchSecondPoint);
                    invalidateView(pParent);
                }
                else {
                    let clx = clientX(paint.touchDownView);
                    let cly = clientY(paint.touchDownView);
                    if (evt.touches.length >= 1) {
                        paint.firstTouch = true;
                        paint.touchFirstPoint = getTouchPostion(evt, canvas, 0, paint);
                        paint.touchFirstPoint.x -= clx;
                        paint.touchFirstPoint.y -= cly;
                    }
                    if (evt.touches.length >= 2) {
                        paint.secondTouch = true;
                        paint.touchSecondPoint = getTouchPostion(evt, canvas, 1, paint);
                        paint.touchSecondPoint.x -= clx;
                        paint.touchSecondPoint.y -= cly;
                    }
                    if (callBack) {
                        callBack(paint.touchDownView, paint.firstTouch, paint.touchFirstPoint, paint.secondTouch, paint.touchSecondPoint);
                    }
                    else if (paint.onTouchMove != null && paint.touchDownView.onTouchMove == null) {
                        paint.onTouchMove(paint.touchDownView, paint.firstTouch, paint.touchFirstPoint, paint.secondTouch, paint.touchSecondPoint);
                    }
                    else {
                        onTouchMoveDefault(paint.touchDownView, paint.firstTouch, paint.touchFirstPoint, paint.secondTouch, paint.touchSecondPoint);
                    }
                    if (paint.touchDownView.resizePoint != -1) {
                        let newBounds = new FCRect(paint.touchDownView.startRect.left, paint.touchDownView.startRect.top, paint.touchDownView.startRect.right, paint.touchDownView.startRect.bottom);
                        windowResize(newBounds, paint.touchDownView.resizePoint, mp, paint.touchDownPoint);
                        paint.touchDownView.location = new FCPoint(newBounds.left, newBounds.top);
                        paint.touchDownView.size = new FCSize(newBounds.right - newBounds.left, newBounds.bottom - newBounds.top);
                        if (paint.touchDownView.parent) {
                            if (paint.touchDownView.parent.paint) {
                                invalidateView(paint.touchDownView.parent);
                            }
                        }
                        else {
                            if (paint) {
                                invalidate(paint);
                            }
                        }
                    }
                    else if (paint.touchDownView.allowDrag) {
                        if (Math.abs(mp.x - paint.touchDownPoint.x) > 5 || Math.abs(mp.y - paint.touchDownPoint.y) > 5) {
                            paint.dragBeginRect = new FCRect(paint.touchDownView.location.x, paint.touchDownView.location.y, paint.touchDownView.location.x + paint.touchDownView.size.cx, paint.touchDownView.location.y + paint.touchDownView.size.cy);
                            paint.dragBeginPoint = new FCPoint(paint.touchDownPoint.x, paint.touchDownPoint.y);
                            paint.draggingView = paint.touchDownView;
                            paint.touchDownView = null;
                        }
                    }
                    else {
                        paint.touchDownPoint = mp;
                    }
                }
                if (paint.touchDownView && paint.touchDownView.allowDragScroll) {
                    evt.preventDefault && evt.preventDefault();
                    evt.returnValue = false;
                    evt.stopPropagation && evt.stopPropagation();
                }
            }
            else if (paint.draggingView != null) {
                let mp = getTouchPostion(evt, canvas, 0, paint);
                paint.touchDownPoint = mp;
                let offsetX = mp.x - paint.dragBeginPoint.x;
                let offsetY = mp.y - paint.dragBeginPoint.y;
                let newBounds = new FCRect(paint.dragBeginRect.left + offsetX, paint.dragBeginRect.top + offsetY, paint.dragBeginRect.right + offsetX, paint.dragBeginRect.bottom + offsetY);
                paint.draggingView.location = new FCPoint(newBounds.left, newBounds.top);
                if (paint.draggingView.parent && paint.draggingView.parent.viewType == "split") {
                    resetSplitLayoutDiv(paint.draggingView.parent);
                    if (paint.onUpdateView) {
                        paint.onUpdateView(paint.draggingView.parent.views);
                    }
                    else {
                        updateViewDefault(paint.draggingView.parent.views);
                    }
                }
                if (paint.draggingView.parent) {
                    if (paint.draggingView.parent.paint) {
                        invalidateView(paint.draggingView.parent);
                    }
                }
                else {
                    if (paint) {
                        invalidate(paint);
                    }
                }
                if (paint.draggingView && paint.draggingView.allowDragScroll) {
                    evt.preventDefault && evt.preventDefault();
                    evt.returnValue = false;
                    evt.stopPropagation && evt.stopPropagation();
                }
            }
        }
        return false;
    };
}
/*
* 添加触摸结束的方法
* canvas:图层
* callBack:回调函数
*/
function addTouchEndEvent(canvas, paint, callBack, clickCallBack) {
    canvas.ontouchend = function (evt) {
        if (paint.isMobile) {
            if (paint.touchDownView) {
                let touchDownView = paint.touchDownView;
                let mp = paint.touchDownPoint;
                let view = findView(mp, paint.views);
                let clicks = 1;
                if (paint.isDoubleClick) {
                    clicks = 2;
                }
                if (view != null && view == paint.touchDownView) {
                    let cmp = new FCPoint(mp.x - clientX(paint.touchDownView), mp.y - clientY(paint.touchDownView));
                    if (clickCallBack) {
                        clickCallBack(paint.touchDownView, true, cmp, false, cmp, clicks);
                    }
                    else if (paint.onClick != null && paint.touchDownView.onClick == null) {
                        paint.onClick(paint.touchDownView, true, cmp, false, cmp, clicks);
                    }
                    else {
                        onClickDefault(paint.touchDownView, true, cmp, false, cmp, clicks);
                    }
                }
                paint.touchDownView.resizePoint = -1;
                paint.touchDownView = null;
                if (callBack) {
                    callBack(touchDownView, paint.firstTouch, paint.touchFirstPoint, paint.secondTouch, paint.touchSecondPoint);
                }
                else if (paint.onTouchEnd != null && touchDownView.onTouchEnd == null) {
                    paint.onTouchEnd(touchDownView, paint.firstTouch, paint.touchFirstPoint, paint.secondTouch, paint.touchSecondPoint);
                }
                else {
                    onTouchEndDefault(touchDownView, paint.firstTouch, paint.touchFirstPoint, paint.secondTouch, paint.touchSecondPoint);
                }
            }
            paint.draggingView = null;
        }
    };
}
/*
* 添加键盘按下事件
* canvas:图层
* callBack:回调函数
*/
function addKeyDownEvent(canvas, paint, callBack) {
    document.onkeydown = function (evt) {
        if (document.activeElement.contains(canvas)) {
            if (paint.focusedView) {
                if (paint.focusedView.onKeyDown != null) {
                    onKeyDownDefault(paint.focusedView, evt.key);
                }
                else {
                    if (callBack) {
                        callBack(paint.focusedView, evt.key);
                    }
                    else if (paint.onKeyDown != null) {
                        paint.onKeyDown(paint.focusedView, evt.key);
                    }
                    else {
                        onKeyDownDefault(paint.focusedView, evt.key);
                    }
                }
            }
        }
    };
}
;
/*
* 添加键盘抬起事件
* canvas:图层
* callBack:回调函数
*/
function addKeyUpEvent(canvas, paint, callBack) {
    document.onkeyup = function (evt) {
        if (document.activeElement.contains(canvas)) {
            if (paint.focusedView) {
                if (paint.focusedView.onKeyUp != null) {
                    onKeyUpDefault(paint.focusedView, evt.key);
                }
                else {
                    if (callBack) {
                        callBack(paint.focusedView, evt.key);
                    }
                    else if (paint.onKeyUp != null) {
                        paint.onKeyUp(paint.focusedView, evt.key);
                    }
                    else {
                        onKeyUpDefault(paint.focusedView, evt.key);
                    }
                }
            }
        }
    };
}
;
/*
* 添加默认的事件
* canvas:图层
* paint:绘图对象
*/
function addDefaultEvent(canvas, paint) {
    addMouseDownEvent(canvas, paint, null);
    addMouseMoveEvent2(canvas, paint, null, null, null);
    addMouseWheelEvent(canvas, paint, null);
    addMouseUpEvent(canvas, paint, null, null);
    addTouchBeginEvent(canvas, paint, null);
    addTouchMoveEvent(canvas, paint, null);
    addTouchEndEvent(canvas, paint, null, null);
    addKeyDownEvent(canvas, paint, null);
    addKeyUpEvent(canvas, paint, null);
}
;
/*
* 是否移动端
*/
function isMobileMode() {
    let ua = navigator.userAgent;
    let ipad = ua.match(/(iPad).*OS\s([\d_]+)/), isIphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/), isAndroid = ua.match(/(Android)\s+([\d.]+)/);
    if (isIphone || isAndroid) {
        return true;
    }
    else {
        return false;
    }
}
/*
* 设置属性
* view:视图
* node:xml节点
*/
function setAttributeDefault(view, node) {
    if (view.paint) {
        if (view.paint.defaultUIStyle == "dark") {
            view.backColor = "rgb(0,0,0)";
            view.borderColor = "rgb(100,100,100)";
            view.textColor = "rgb(255,255,255)";
            view.scrollBarColor = "rgb(100,100,100)";
        }
        else if (view.paint.defaultUIStyle == "light") {
            view.backColor = "rgb(255,255,255)";
            view.borderColor = "rgb(150,150,150)";
            view.textColor = "rgb(0,0,0)";
            view.scrollBarColor = "rgb(200,200,200)";
        }
    }
    if (!view.location) {
        view.location = new FCPoint(0, 0);
    }
    if (!view.size) {
        view.size = new FCSize(100, 30);
    }
    for (let i = 0; i < node.attributes.length; i++) {
        let name = node.attributes[i].nodeName.toLowerCase();
        let value = node.attributes[i].nodeValue;
        if (name && value) {
            if (name == "location") {
                let xStr = value.split(',')[0];
                let yStr = value.split(',')[1];
                if (xStr.indexOf("%") != -1) {
                    view.exAttributes.set("leftstr", xStr);
                }
                else {
                    view.location.x = parseInt(xStr);
                }
                if (yStr.indexOf("%") != -1) {
                    view.exAttributes.set("topstr", yStr);
                }
                else {
                    view.location.y = parseInt(yStr);
                }
            }
            else if (name == "size") {
                let xStr = value.split(',')[0];
                let yStr = value.split(',')[1];
                if (xStr.indexOf("%") != -1) {
                    view.exAttributes.set("widthstr", xStr);
                }
                else {
                    view.size.cx = parseInt(xStr);
                }
                if (yStr.indexOf("%") != -1) {
                    view.exAttributes.set("heightstr", yStr);
                }
                else {
                    view.size.cy = parseInt(yStr);
                }
            }
            else if (name == "text") {
                view.text = value;
            }
            else if (name == "backcolor") {
                let lowerStr = value.toLowerCase();
                if (lowerStr.indexOf("rgb") == 0) {
                    view.backColor = value;
                }
                else {
                    view.backColor = null;
                }
            }
            else if (name == "bordercolor") {
                let lowerStr = value.toLowerCase();
                if (lowerStr.indexOf("rgb") == 0) {
                    view.borderColor = value;
                }
                else {
                    view.borderColor = null;
                }
            }
            else if (name == "textcolor") {
                let lowerStr = value.toLowerCase();
                if (lowerStr.indexOf("rgb") == 0) {
                    view.textColor = value;
                }
                else {
                    view.textColor = null;
                }
            }
            else if (name == "layoutstyle") {
                if (view.viewType == "layout") {
                    view.layoutStyle = value.toLowerCase();
                }
                else if (view.viewType == "split") {
                    view.layoutStyle = value.toLowerCase();
                }
            }
            else if (name == "align") {
                view.align = value.toLowerCase();
            }
            else if (name == "cursor") {
                view.cursor = value.toLowerCase();
            }
            else if (name == "vertical-align") {
                view.verticalAlign = value.toLowerCase();
            }
            else if (name == "dock") {
                view.dock = value.toLowerCase();
            }
            else if (name == "font") {
                view.font = value;
            }
            else if (name == "headerheight") {
                if (view.viewType == "grid") {
                    view.headerHeight = Number(value);
                }
                else if (view.viewType == "tree") {
                    ;
                    view.headerHeight = Number(value);
                }
            }
            else if (name == "cornerradius") {
                view.cornerRadius = Number(value);
            }
            else if (name == "borderwidth") {
                view.borderWidth = Number(value);
            }
            else if (name == "splitmode") {
                view.splitMode = value.toLowerCase();
            }
            else if (name == "autowrap") {
                view.autoWrap = value.toLowerCase() == "true";
            }
            else if (name == "name") {
                view.viewName = value;
            }
            else if (name == "tabindex") {
                view.tabIndex = Number(value);
            }
            else if (name == "tabstop") {
                view.tabStop = value.toLowerCase() == "true";
            }
            else if (name == "enabled") {
                view.enabled = value.toLowerCase() == "true";
            }
            else if (name == "showvscrollbar") {
                view.showVScrollBar = value.toLowerCase() == "true";
            }
            else if (name == "showhscrollbar") {
                view.showHScrollBar = value.toLowerCase() == "true";
            }
            else if (name == "visible") {
                view.visible = value.toLowerCase() == "true";
            }
            else if (name == "displayoffset") {
                view.displayOffset = value.toLowerCase() == "true";
            }
            else if (name == "checked") {
                if (view.viewType == "checkbox") {
                    view.checked = value.toLowerCase() == "true";
                }
                else if (view.viewType == "radiobutton") {
                    view.checked = value.toLowerCase() == "true";
                }
            }
            else if (name == "buttonsize") {
                if (view.viewType == "checkbox") {
                    view.buttonSize = new FCSize(Number(value.split(',')[0]), Number(value.split(',')[1]));
                }
                else if (view.viewType == "radiobutton") {
                    view.buttonSize = new FCSize(Number(value.split(',')[0]), Number(value.split(',')[1]));
                }
            }
            else if (name == "topmost") {
                view.topMost = value.toLowerCase() == "true";
            }
            else if (name == "groupname") {
                view.groupName = value;
            }
            else if (name == "allowdragscroll") {
                view.allowDragScroll = value.toLowerCase() == "true";
            }
            else if (name == "allowpreviewsevent") {
                view.allowPreviewsEvent = value.toLowerCase() == "true";
            }
            else if (name == "allowdrag") {
                view.allowDrag = value.toLowerCase() == "true";
            }
            else if (name == "allowresize") {
                view.allowResize = value.toLowerCase() == "true";
            }
            else if (name == "indent") {
                view.indent = Number(value);
            }
            else if (name == "showcheckbox") {
                view.showCheckBox = value.toLowerCase() == "true";
            }
            else if (name == "padding") {
                view.padding = new FCPadding(Number(value.split(',')[0]), Number(value.split(',')[1]), Number(value.split(',')[2]), Number(value.split(',')[3]));
            }
            else if (name == "margin") {
                view.margin = new FCPadding(Number(value.split(',')[0]), Number(value.split(',')[1]), Number(value.split(',')[2]), Number(value.split(',')[3]));
            }
            else if (name == "hoveredcolor") {
                let lowerStr = value.toLowerCase();
                if (lowerStr.indexOf("rgb") == 0) {
                    view.hoveredColor = value;
                }
                else {
                    view.hoveredColor = null;
                }
            }
            else if (name == "pushedcolor") {
                let lowerStr = value.toLowerCase();
                if (lowerStr.indexOf("rgb") == 0) {
                    view.pushedColor = value;
                }
                else {
                    view.pushedColor = null;
                }
            }
            else if (name == "layout") {
                view.layout = value;
            }
            else if (name == "width") {
                if (value.indexOf("%") != -1) {
                    view.exAttributes.set("widthstr", value);
                }
                else {
                    view.size.cx = parseInt(value);
                }
            }
            else if (name == "height") {
                if (value.indexOf("%") != -1) {
                    view.exAttributes.set("heightstr", value);
                }
                else {
                    view.size.cy = parseInt(value);
                }
            }
            else if (name == "top") {
                if (value.indexOf("%") != -1) {
                    view.exAttributes.set("topstr", value);
                }
                else {
                    view.location.y = parseInt(value);
                }
            }
            else if (name == "left") {
                if (value.indexOf("%") != -1) {
                    view.exAttributes.set("leftstr", value);
                }
                else {
                    view.location.x = parseInt(value);
                }
            }
            else {
                view.exAttributes.set(name, value);
            }
        }
    }
}
;
/*
* 读取Xml中的树节点
* tree 树
* parentNode 父节点
* xmlNode Xml节点
*/
function readTreeXmlNodeDefault(tree, parentNode, xmlNode) {
    let subNodes = xmlNode.childNodes;
    let treeNode = new FCTreeNode();
    treeNode.value = xmlNode.getAttribute("text");
    appendTreeNode(tree, treeNode, parentNode);
    for (let i = 0; i < subNodes.length; i++) {
        let child = subNodes[i];
        if (child.nodeType == 1) {
            let nodeName = child.nodeName.toLowerCase();
            if (nodeName == "node") {
                readTreeXmlNodeDefault(tree, treeNode, child);
            }
        }
    }
}
;
/*
* 读取Xml
* paint 绘图对象
* node节点
* parent 父视图
*/
function readXmlNodeDefault(paint, node, parent) {
    let subNodes = node.childNodes;
    for (let i = 0; i < subNodes.length; i++) {
        let s = subNodes[i];
        if (s.nodeType == 1) {
            let child = s;
            let view = null;
            let viewType = "";
            let nodeName = child.nodeName.toLowerCase();
            if (nodeName == "div" || nodeName == "view") {
                viewType = child.getAttribute("type");
                if (viewType == "splitlayout") {
                    view = new FCSplitLayoutDiv();
                }
                else if (viewType == "layout") {
                    view = new FCLayoutDiv();
                }
                else if (viewType == "tab") {
                    view = new FCTabView();
                }
                else if (viewType == "tabpage") {
                    view = new FCTabPage();
                }
                else if (viewType == "radio") {
                    view = new FCRadioButton();
                }
                else if (viewType == "text") {
                    view = new FCTextBox();
                }
                else if (viewType == "checkbox") {
                    view = new FCCheckBox();
                }
                else if (viewType == "range") {
                    view = new FCSpin();
                }
                else if (viewType == "custom") {
                    let cid = child.getAttribute("cid");
                    view = new FCDiv();
                    view.viewType = cid;
                }
                else {
                    view = new FCDiv();
                }
            }
            else if (nodeName == "select") {
                view = new FCComboBox();
            }
            else if (nodeName == "input") {
                viewType = child.getAttribute("type");
                if (viewType == "radio") {
                    view = new FCRadioButton();
                }
                else if (viewType == "text") {
                    view = new FCTextBox();
                }
                else if (viewType == "checkbox") {
                    view = new FCCheckBox();
                }
                else if (viewType == "range") {
                    view = new FCSpin();
                }
                else if (viewType == "custom") {
                    let cid = child.getAttribute("cid");
                    view = new FCView();
                    view.viewType = cid;
                }
                else {
                    view = new FCButton();
                }
            }
            else if (nodeName == "chart") {
                view = new FCChart();
            }
            else if (nodeName == "calendar") {
                view = new FCCalendar();
            }
            else if (nodeName == "table") {
                view = new FCGrid();
            }
            else if (nodeName == "tree") {
                view = new FCTree();
            }
            else if (nodeName == "label") {
                view = new FCLabel();
            }
            else {
                view = new FCView();
            }
            view.views = new Array();
            view.paint = paint;
            view.parent = parent;
            setAttributeDefault(view, child);
            if (paint.editMode == 0) {
                if (viewType == "text") {
                    createInputTextBox(view);
                }
                else if (viewType == "range") {
                    createInputTextBox(view);
                }
            }
            if (view) {
                if (viewType == "tabpage") {
                    let tabButton = new FCView();
                    tabButton.viewType = "tabbutton";
                    let atrHeaderSize = child.getAttribute("headersize");
                    if (atrHeaderSize) {
                        tabButton.size = new FCSize(parseInt(atrHeaderSize.split(',')[0]), parseInt(atrHeaderSize.split(',')[1]));
                    }
                    else {
                        tabButton.size = new FCSize(100, 20);
                    }
                    if (view.paint.defaultUIStyle == "dark") {
                        tabButton.backColor = "rgb(0,0,0)";
                        tabButton.borderColor = "rgb(100,100,100)";
                        tabButton.textColor = "rgb(255,255,255)";
                    }
                    else if (view.paint.defaultUIStyle == "light") {
                        tabButton.backColor = "rgb(255,255,255)";
                        tabButton.borderColor = "rgb(150,150,150)";
                        tabButton.textColor = "rgb(0,0,0)";
                    }
                    tabButton.text = view.text;
                    addTabPage(view.parent, view, tabButton);
                }
                else {
                    if (parent) {
                        if (!parent.views) {
                            parent.views = new Array();
                        }
                        parent.views.push(view);
                    }
                    else {
                        paint.views.push(view);
                    }
                }
                if (viewType == "splitlayout") {
                    let atrDatum = child.getAttribute("datumsize");
                    if (atrDatum) {
                        view.size = new FCSize(parseInt(atrDatum.split(',')[0]), parseInt(atrDatum.split(',')[1]));
                    }
                    let splitter = new FCView();
                    splitter.parent = view;
                    splitter.paint = paint;
                    if (view.paint.defaultUIStyle == "dark") {
                        splitter.backColor = "rgb(75,75,75)";
                    }
                    else if (view.paint.defaultUIStyle == "light") {
                        splitter.backColor = "rgb(150,150,150)";
                    }
                    splitter.borderColor = "none";
                    let canDragSplitter = child.getAttribute("candragsplitter");
                    if (canDragSplitter) {
                        if (canDragSplitter == "true") {
                            splitter.allowDrag = true;
                        }
                    }
                    view.views.push(splitter);
                    view.splitter = splitter;
                    let splitterposition = child.getAttribute("splitterposition");
                    let splitStr = splitterposition.split(',');
                    if (splitStr.length >= 4) {
                        let splitRect = new FCRect(parseFloat(splitStr[0]), parseFloat(splitStr[1]), parseFloat(splitStr[2]), parseFloat(splitStr[3]));
                        splitter.location = new FCPoint(splitRect.left, splitRect.top);
                        splitter.size = new FCSize(splitRect.right - splitRect.left, splitRect.bottom - splitRect.top);
                    }
                    else {
                        let sSize = parseFloat(splitStr[1]);
                        let sPosition = parseFloat(splitStr[0]);
                        if (view.layoutStyle == "lefttoright" || view.layoutStyle == "righttoleft") {
                            splitter.location = new FCPoint(sPosition, 0);
                            splitter.size = new FCSize(sSize, view.size.cy);
                        }
                        else {
                            splitter.location = new FCPoint(0, sPosition);
                            splitter.size = new FCSize(view.size.cx, sSize);
                        }
                    }
                    readXmlNodeDefault(paint, child, view);
                    view.firstView = view.views[1];
                    view.secondView = view.views[2];
                    view.oldSize = view.size;
                    resetSplitLayoutDiv(view);
                }
                else if (viewType == "tab") {
                    readXmlNodeDefault(paint, child, view);
                    if (view.tabPages.length > 0) {
                        let strSelectedIndex = child.getAttribute("selectedindex");
                        if (strSelectedIndex) {
                            let selectedIndex = parseInt(strSelectedIndex);
                            if (selectedIndex >= 0 && selectedIndex < view.tabPages.length) {
                                view.tabPages[selectedIndex].visible = true;
                            }
                        }
                        else {
                            view.tabPages[view.tabPages.length - 1].visible = true;
                        }
                    }
                }
                else if (nodeName == "table") {
                    let tSubNodes = child.childNodes;
                    for (let n = 0; n < tSubNodes.length; n++) {
                        let tChild = tSubNodes[n];
                        if (tChild.nodeType == 1) {
                            if (tChild.nodeName == "tr") {
                                let tsunNodes = tChild.childNodes;
                                let gridRow = null;
                                for (let j = 0; j < tsunNodes.length; j++) {
                                    let sunNodeName = tsunNodes[j].nodeName.toLowerCase();
                                    if (sunNodeName.toLowerCase() == "th") {
                                        let gridColumn = new FCGridColumn;
                                        gridColumn.width = 100;
                                        if (view.paint.defaultUIStyle == "light") {
                                            gridColumn.backColor = "rgb(230,230,230)";
                                            gridColumn.borderColor = "rgb(150,150,150)";
                                            gridColumn.textColor = "rgb(0,0,0)";
                                        }
                                        else if (view.paint.defaultUIStyle == "dark") {
                                            gridColumn.backColor = "rgb(50,50,50)";
                                            gridColumn.borderColor = "rgb(100,100,100)";
                                            gridColumn.textColor = "rgb(255,255,255)";
                                        }
                                        let widthAttr = tsunNodes[j].getAttribute("width");
                                        if (widthAttr) {
                                            if (widthAttr.indexOf("%") != -1) {
                                                gridColumn.widthStr = widthAttr;
                                            }
                                            else {
                                                gridColumn.width = parseFloat(widthAttr);
                                            }
                                        }
                                        let backColorAttr = tsunNodes[j].getAttribute("backcolor");
                                        if (backColorAttr) {
                                            gridColumn.backColor = backColorAttr;
                                        }
                                        let textColorAttr = tsunNodes[j].getAttribute("textcolor");
                                        if (textColorAttr) {
                                            gridColumn.textColor = textColorAttr;
                                        }
                                        let borderColorAttr = tsunNodes[j].getAttribute("bordercolor");
                                        if (borderColorAttr) {
                                            gridColumn.borderColor = borderColorAttr;
                                        }
                                        let fontAttr = tsunNodes[j].getAttribute("font");
                                        if (fontAttr) {
                                            gridColumn.font = fontAttr;
                                        }
                                        gridColumn.text = tsunNodes[j].getAttribute("text");
                                        view.columns.push(gridColumn);
                                    }
                                    else if (sunNodeName.toLowerCase() == "td") {
                                        if (!gridRow) {
                                            gridRow = new FCGridRow();
                                            view.rows.push(gridRow);
                                        }
                                        let gridCell = new FCGridCell();
                                        gridCell.value = tsunNodes[j].textContent;
                                        gridRow.cells.push(gridCell);
                                    }
                                }
                            }
                        }
                    }
                }
                else if (nodeName == "tree") {
                    let treeColumn = new FCTreeColumn();
                    view.columns.push(treeColumn);
                    let tSubNodes = child.childNodes;
                    let columnWidth = 0;
                    for (let n = 0; n < tSubNodes.length; n++) {
                        let tChild = tSubNodes[n];
                        if (tChild.nodeType == 1) {
                            if (tChild.nodeName == "nodes") {
                                let tsunNodes = tChild.childNodes;
                                for (let j = 0; j < tsunNodes.length; j++) {
                                    let sunNodeName = tsunNodes[j].nodeName.toLowerCase();
                                    if (sunNodeName.toLowerCase() == "node") {
                                        readTreeXmlNodeDefault(view, null, tsunNodes[j]);
                                    }
                                }
                            }
                            else if (tChild.nodeName == "tr") {
                                let tsunNodes = tChild.childNodes;
                                for (let j = 0; j < tsunNodes.length; j++) {
                                    let sunNodeName = tsunNodes[j].nodeName.toLowerCase();
                                    if (sunNodeName.toLowerCase() == "th") {
                                        let widthAttr = tsunNodes[j].getAttribute("width");
                                        if (widthAttr) {
                                            if (widthAttr.indexOf("%") != -1) {
                                                treeColumn.widthStr = widthAttr;
                                            }
                                            else {
                                                columnWidth += parseFloat(widthAttr);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (columnWidth > 0) {
                        treeColumn.width = columnWidth;
                    }
                }
                else if (nodeName == "calendar") {
                    initCalendar(view);
                    let month = getYear(view.years, 2022).months.get(10);
                    let day = month.days.get(1);
                    view.selectedDay = day;
                    updateCalendar(view);
                }
                else if (nodeName == "select") {
                    view.dropDownMenu = new FCMenu();
                    view.dropDownMenu.comboBox = view;
                    addView(view.dropDownMenu, paint);
                    view.dropDownMenu.size.cx = view.size.cx;
                    let tSubNodes = child.childNodes;
                    for (let n = 0; n < tSubNodes.length; n++) {
                        let tChild = tSubNodes[n];
                        if (tChild.nodeType == 1) {
                            if (tChild.nodeName == "option") {
                                let menuItem = new FCMenuItem();
                                addMenuItem(menuItem, view.dropDownMenu);
                                setAttributeDefault(menuItem, tChild);
                            }
                        }
                    }
                    if (view.dropDownMenu.items.length > 0) {
                        let strSelectedIndex = child.getAttribute("selectedindex");
                        if (strSelectedIndex) {
                            let selectedIndex = parseInt(strSelectedIndex);
                            if (selectedIndex >= 0 && selectedIndex < view.dropDownMenu.items.length) {
                                view.selectedIndex = selectedIndex;
                                view.text = view.dropDownMenu.items[selectedIndex].text;
                            }
                            else {
                                view.selectedIndex = 0;
                                view.text = view.dropDownMenu.items[0].text;
                            }
                        }
                        else {
                            view.selectedIndex = 0;
                            view.text = view.dropDownMenu.items[0].text;
                        }
                    }
                }
                else {
                    if (view.viewType != "chart") {
                        readXmlNodeDefault(paint, child, view);
                    }
                }
            }
        }
    }
}
/*
* 加载图形界面
* paint:绘图对象
* xml:Xml内容
* size:尺寸大小
*/
function renderFaceCat(paint, xml) {
    let xmlDoc = new DOMParser().parseFromString(xml, "text/xml");
    let rootNode = xmlDoc.getElementsByTagName('body')[0];
    readXmlNodeDefault(paint, rootNode, null);
    if (paint.onUpdateView) {
        paint.onUpdateView(paint.views);
    }
    else {
        updateViewDefault(paint.views);
    }
    invalidate(paint);
}
;
/*
* 重绘复选按钮
* checkBox:视图
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawCheckBox(checkBox, paint, clipRect) {
    let width = checkBox.size.cx, height = checkBox.size.cy;
    if (checkBox.textColor && checkBox.textColor != "none") {
        let eRight = checkBox.buttonSize.cx + 10;
        let eRect = new FCRect(1, (height - checkBox.buttonSize.cy) / 2, checkBox.buttonSize.cx + 1, (height + checkBox.buttonSize.cy) / 2);
        if (checkBox.text.length == 0) {
            eRect = new FCRect((width - checkBox.buttonSize.cx) / 2, (height - checkBox.buttonSize.cy) / 2, (width + checkBox.buttonSize.cx) / 2, (height + checkBox.buttonSize.cy) / 2);
        }
        paint.drawRect(checkBox.textColor, 1, null, eRect.left, eRect.top, eRect.right, eRect.bottom);
        if (checkBox.checked) {
            eRect.left += 2;
            eRect.top += 2;
            eRect.right -= 2;
            eRect.bottom -= 2;
            paint.beginPath();
            paint.addLine(eRect.left, eRect.top + 8, eRect.left + 6, eRect.bottom);
            paint.addLine(eRect.left + 6, eRect.bottom, eRect.right - 1, eRect.top);
            paint.drawPath(checkBox.textColor, 1, []);
            paint.closePath();
        }
        if (checkBox.text.length > 0) {
            let tSize = paint.textSize(checkBox.text, checkBox.font);
            paint.drawText(checkBox.text, checkBox.textColor, checkBox.font, eRight, height / 2 - tSize.cy / 2);
        }
    }
}
/*
* 重绘单选按钮
* radioButton:视图
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawRadioButton(radioButton, paint, clipRect) {
    let width = radioButton.size.cx, height = radioButton.size.cy;
    if (radioButton.textColor && radioButton.textColor != "none") {
        let eRight = radioButton.buttonSize.cx + 10;
        let eRect = new FCRect(1, (height - radioButton.buttonSize.cy) / 2, radioButton.buttonSize.cx + 1, (height + radioButton.buttonSize.cy) / 2);
        paint.drawEllipse(radioButton.textColor, 1, null, eRect.left, eRect.top, eRect.right, eRect.bottom);
        if (radioButton.checked) {
            eRect.left += 2;
            eRect.top += 2;
            eRect.right -= 2;
            eRect.bottom -= 2;
            paint.fillEllipse(radioButton.textColor, eRect.left, eRect.top, eRect.right, eRect.bottom);
        }
        let tSize = paint.textSize(radioButton.text, radioButton.font);
        paint.drawText(radioButton.text, radioButton.textColor, radioButton.font, eRight, height / 2 - tSize.cy / 2);
    }
}
/*
* 重绘按钮
* button:视图
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawButton(button, paint, clipRect) {
    if (button == paint.touchDownView) {
        if (button.pushedColor && button.pushedColor != "none") {
            paint.fillRoundRect(button.pushedColor, 0, 0, button.size.cx, button.size.cy, button.cornerRadius);
        }
        else {
            if (button.backColor && button.backColor != "none") {
                paint.fillRoundRect(button.backColor, 0, 0, button.size.cx, button.size.cy, button.cornerRadius);
            }
        }
    }
    else if (button == paint.touchMoveView) {
        if (button.hoveredColor && button.hoveredColor != "none") {
            paint.fillRoundRect(button.hoveredColor, 0, 0, button.size.cx, button.size.cy, button.cornerRadius);
        }
        else {
            if (button.backColor && button.backColor != "none") {
                paint.fillRoundRect(button.backColor, 0, 0, button.size.cx, button.size.cy, button.cornerRadius);
            }
        }
    }
    else if (button.backColor && button.backColor != "none") {
        paint.fillRoundRect(button.backColor, 0, 0, button.size.cx, button.size.cy, button.cornerRadius);
    }
    if (button.textColor && button.textColor != "none" && button.text) {
        let tSize = paint.textSize(button.text, button.font);
        paint.drawText(button.text, button.textColor, button.font, (button.size.cx - tSize.cx) / 2, button.size.cy / 2 - tSize.cy / 2);
    }
    if (button.borderColor && button.borderColor != "none") {
        paint.drawRoundRect(button.borderColor, button.borderWidth, [], 0, 0, button.size.cx, button.size.cy, button.cornerRadius);
    }
}
/*
* 点击复选按钮
* checkBox:视图
* mp:坐标
*/
function clickCheckBox(checkBox, mp) {
    checkBox.checked = !checkBox.checked;
}
/*
* 点击单选按钮
* radioButton:视图
* mp: 坐标
*/
function clickRadioButton(radioButton, mp) {
    if (radioButton.parent && radioButton.parent.views) {
        for (let i = 0; i < radioButton.parent.views.length; i++) {
            let rView = radioButton.parent.views[i];
            if (rView != radioButton &&
                rView.groupName == radioButton.groupName) {
                rView.checked = false;
            }
        }
    }
    radioButton.checked = true;
}
/*
* 获取月的日数
* year:年
* month:月
*/
function getDaysInMonth(year, month) {
    switch (month) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            return 31;
        case 4:
        case 6:
        case 9:
        case 11:
            return 30;
        case 2:
            if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
                return 29;
            else
                return 28;
    }
    return 0;
}
/*
* 根据字符获取月份
* month:月
*/
function getMonthStr(month) {
    switch (month) {
        case 1:
            return "一月";
        case 2:
            return "二月";
        case 3:
            return "三月";
        case 4:
            return "四月";
        case 5:
            return "五月";
        case 6:
            return "六月";
        case 7:
            return "七月";
        case 8:
            return "八月";
        case 9:
            return "九月";
        case 10:
            return "十月";
        case 11:
            return "十一月";
        case 12:
            return "十二月";
        default:
            return "";
    }
}
/*
* 获取年
* years:年的集合
* year:年
*/
function getYear(calendar, year) {
    let cy = null;
    if (!calendar.years.has(year)) {
        cy = new CYear();
        cy.year = year;
        calendar.years.set(year, cy);
        for (let i = 1; i <= 12; i++) {
            let cMonth = new CMonth();
            cMonth.year = year;
            cMonth.month = i;
            cy.months.set(i, cMonth);
            let daysInMonth = getDaysInMonth(year, i);
            for (let j = 1; j <= daysInMonth; j++) {
                let cDay = new CDay();
                cDay.year = year;
                cDay.month = i;
                cDay.day = j;
                cMonth.days.set(j, cDay);
            }
        }
    }
    else {
        cy = calendar.years.get(year);
    }
    return cy;
}
/*
* 显示隐藏日期层
* dayDiv:日期层
* visible:是否可见
*/
function showOrHideDayDiv(dayDiv, visible) {
    let dayButtonSize = dayDiv.dayButtons.length;
    for (let i = 0; i < dayButtonSize; i++) {
        let dayButton = dayDiv.dayButtons[i];
        dayButton.visible = visible;
    }
}
/*
* 显示隐藏月层
* monthDiv:月层
* visible:是否可见
*/
function showOrHideMonthDiv(monthDiv, visible) {
    let monthButtonSize = monthDiv.monthButtons.length;
    for (let i = 0; i < monthButtonSize; i++) {
        let monthButton = monthDiv.monthButtons[i];
        monthButton.visible = visible;
    }
}
/*
* 显示隐藏年层
* yearButtons:年层
* visible:是否可见
*/
function showOrHideYearDiv(yearDiv, visible) {
    let yearButtonSize = yearDiv.yearButtons.length;
    for (let i = 0; i < yearButtonSize; i++) {
        let yearButton = yearDiv.yearButtons[i];
        yearButton.visible = visible;
    }
}
/*
* 初始化日历
* calendar:日历
*/
function initCalendar(calendar) {
    for (let i = 0; i < 42; i++) {
        let dayButton = new DayButton();
        calendar.dayDiv.dayButtons.push(dayButton);
        let dayFCButtonm = new DayButton();
        dayFCButtonm.visible = false;
        calendar.dayDiv.dayButtonsAm.push(dayFCButtonm);
    }
    for (let i = 0; i < 12; i++) {
        let monthButton = new MonthButton();
        monthButton.month = (i + 1);
        calendar.monthDiv.monthButtons.push(monthButton);
        let monthButtonAm = new MonthButton();
        monthButtonAm.visible = false;
        monthButtonAm.month = (i + 1);
        calendar.monthDiv.monthButtonsAm.push(monthButtonAm);
    }
    for (let i = 0; i < 12; i++) {
        let yearButton = new YearButton();
        calendar.yearDiv.yearButtons.push(yearButton);
        let yearButtonAm = new YearButton();
        yearButtonAm.visible = false;
        calendar.yearDiv.yearButtonsAm.push(yearButtonAm);
    }
}
/*
* 获取星期
* y:年
* m:月
* d:日
*/
function dayOfWeek(y, m, d) {
    return Math.floor(((d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) + 1) % 7);
}
/*
* 获取当月
* calendar:日历
*/
function getMonth(calendar) {
    return getYear(calendar, calendar.selectedDay.year).months.get(calendar.selectedDay.month);
}
/*
* 获取下个月
* calendar:日历
* year:年
* month:月
*/
function getNextMonth(calendar, year, month) {
    let nextMonth = month + 1;
    let nextYear = year;
    if (nextMonth == 13) {
        nextMonth = 1;
        nextYear += 1;
    }
    return getYear(calendar, nextYear).months.get(nextMonth);
}
/*
* 获取上个月
* calendar:日历
* year:年
* month:月
*/
function getLastMonth(calendar, year, month) {
    let lastMonth = month - 1;
    let lastYear = year;
    if (lastMonth == 0) {
        lastMonth = 12;
        lastYear -= 1;
    }
    return getYear(calendar, lastYear).months.get(lastMonth);
}
/*
* 重置日期层布局
* calendar:日历
* dayDiv:日期层
* state:状态
*/
function resetDayDiv(calendar, dayDiv, state) {
    let thisMonth = getMonth(calendar);
    let lastMonth = getLastMonth(calendar, thisMonth.year, thisMonth.month);
    let nextMonth = getNextMonth(calendar, thisMonth.year, thisMonth.month);
    let left = 0;
    let headHeight = calendar.headDiv.bounds.bottom;
    let top = headHeight;
    let width = calendar.size.cx;
    let height = calendar.size.cy;
    height -= calendar.timeDiv.bounds.bottom - calendar.timeDiv.bounds.top;
    let dayButtonHeight = height - headHeight;
    if (dayButtonHeight < 1) {
        dayButtonHeight = 1;
    }
    let toY = 0;
    if (dayDiv.aDirection == 1) {
        toY = dayButtonHeight * dayDiv.aTick / dayDiv.aTotalTick;
        if (state == 1) {
            thisMonth = nextMonth;
            let month = thisMonth.month;
            lastMonth = getLastMonth(calendar, thisMonth.year, month);
            nextMonth = getNextMonth(calendar, thisMonth.year, month);
        }
    }
    else if (dayDiv.aDirection == 2) {
        toY = -dayButtonHeight * dayDiv.aTick / dayDiv.aTotalTick;
        if (state == 1) {
            thisMonth = lastMonth;
            let month = thisMonth.month;
            lastMonth = getLastMonth(calendar, thisMonth.year, month);
            nextMonth = getNextMonth(calendar, thisMonth.year, month);
        }
    }
    let buttonSize = 0;
    if (state == 0) {
        buttonSize = dayDiv.dayButtons.length;
    }
    else if (state == 1) {
        buttonSize = dayDiv.dayButtonsAm.length;
    }
    let dheight = dayButtonHeight / 6;
    let days = thisMonth.days;
    let firstDay = days.get(1);
    let startDayOfWeek = dayOfWeek(firstDay.year, firstDay.month, firstDay.day);
    for (let i = 0; i < buttonSize; i++) {
        let dayButton = null;
        if (state == 0) {
            dayButton = dayDiv.dayButtons[i];
            buttonSize = dayDiv.dayButtons.length;
        }
        else if (state == 1) {
            dayButton = dayDiv.dayButtonsAm[i];
            buttonSize = dayDiv.dayButtonsAm.length;
        }
        if (i == 35) {
            dheight = height - top;
        }
        let vOffset = 0;
        if (state == 1) {
            if (dayDiv.aTick > 0) {
                dayButton.visible = true;
                if (dayDiv.aDirection == 1) {
                    vOffset = toY - dayButtonHeight;
                }
                else if (dayDiv.aDirection == 2) {
                    vOffset = toY + dayButtonHeight;
                }
            }
            else {
                dayButton.visible = false;
                continue;
            }
        }
        else {
            vOffset = toY;
        }
        if ((i + 1) % 7 == 0) {
            let dp = new FCPoint(left, top + vOffset);
            let ds = new FCSize(width - left, dheight);
            let bounds = new FCRect(dp.x, dp.y, dp.x + ds.cx, dp.y + ds.cy);
            dayButton.bounds = bounds;
            left = 0;
            if (i != 0 && i != buttonSize - 1) {
                top += dheight;
            }
        }
        else {
            let dp = new FCPoint(left, top + vOffset);
            let ds = new FCSize(width / 7 + ((i + 1) % 7) % 2, dheight);
            let bounds = new FCRect(dp.x, dp.y, dp.x + ds.cx, dp.y + ds.cy);
            dayButton.bounds = bounds;
            left += ds.cx;
        }
        let cDay = null;
        dayButton.inThisMonth = false;
        if (i >= startDayOfWeek && i <= startDayOfWeek + days.size - 1) {
            cDay = days.get(i - startDayOfWeek + 1);
            dayButton.inThisMonth = true;
        }
        else if (i < startDayOfWeek) {
            cDay = lastMonth.days.get(lastMonth.days.size - startDayOfWeek + i + 1);
        }
        else if (i > startDayOfWeek + days.size - 1) {
            cDay = nextMonth.days.get(i - startDayOfWeek - days.size + 1);
        }
        dayButton.day = cDay;
        if (state == 0 && dayButton.day && dayButton.day == calendar.selectedDay) {
            dayButton.selected = true;
        }
        else {
            dayButton.selected = false;
        }
    }
}
/*
* 重置月层布局
* calendar:日历
* monthDiv:月层
* state:状态
*/
function resetMonthDiv(calendar, monthDiv, state) {
    let thisYear = monthDiv.year;
    let lastYear = monthDiv.year - 1;
    let nextYear = monthDiv.year + 1;
    let left = 0;
    let headHeight = calendar.headDiv.bounds.bottom;
    let top = headHeight;
    let width = calendar.size.cx;
    let height = calendar.size.cy;
    height -= calendar.timeDiv.bounds.bottom - calendar.timeDiv.bounds.top;
    let monthButtonHeight = height - top;
    if (monthButtonHeight < 1) {
        monthButtonHeight = 1;
    }
    let toY = 0;
    let monthButtons = [];
    if (monthDiv.aDirection == 1) {
        toY = monthButtonHeight * monthDiv.aTick / monthDiv.aTotalTick;
        if (state == 1) {
            thisYear = nextYear;
            lastYear = thisYear - 1;
            nextYear = thisYear + 1;
        }
    }
    else if (monthDiv.aDirection == 2) {
        toY = -monthButtonHeight * monthDiv.aTick / monthDiv.aTotalTick;
        if (state == 1) {
            thisYear = lastYear;
            lastYear = thisYear - 1;
            nextYear = thisYear + 1;
        }
    }
    if (state == 0) {
        monthButtons = monthDiv.monthButtons;
    }
    else if (state == 1) {
        monthButtons = monthDiv.monthButtonsAm;
    }
    let dheight = monthButtonHeight / 3;
    let buttonSize = monthButtons.length;
    for (let i = 0; i < buttonSize; i++) {
        if (i == 8) {
            dheight = height - top;
        }
        let monthButton = monthButtons[i];
        monthButton.year = thisYear;
        let vOffSet = 0;
        if (state == 1) {
            if (monthDiv.aTick > 0) {
                monthButton.visible = true;
                if (monthDiv.aDirection == 1) {
                    vOffSet = toY - monthButtonHeight;
                }
                else if (monthDiv.aDirection == 2) {
                    vOffSet = toY + monthButtonHeight;
                }
            }
            else {
                monthButton.visible = false;
                continue;
            }
        }
        else {
            vOffSet = toY;
        }
        if ((i + 1) % 4 == 0) {
            let dp = new FCPoint(left, top + vOffSet);
            let ds = new FCSize(width - left, dheight);
            let bounds = new FCRect(dp.x, dp.y, dp.x + ds.cx, dp.y + ds.cy);
            monthButton.bounds = bounds;
            left = 0;
            if (i != 0 && i != buttonSize - 1) {
                top += dheight;
            }
        }
        else {
            let dp = new FCPoint(left, top + vOffSet);
            let ds = new FCSize(width / 4 + ((i + 1) % 4) % 2, dheight);
            let bounds = new FCRect(dp.x, dp.y, dp.x + ds.cx, dp.y + ds.cy);
            monthButton.bounds = bounds;
            left += ds.cx;
        }
    }
}
/*
* 重置年层布局
* calendar:日历
* yearDiv:年层
* state:状态
*/
function resetYearDiv(calendar, yearDiv, state) {
    let thisStartYear = yearDiv.startYear;
    let lastStartYear = yearDiv.startYear - 12;
    let nextStartYear = yearDiv.startYear + 12;
    let left = 0;
    let headHeight = calendar.headDiv.bounds.bottom;
    let top = headHeight;
    let width = calendar.size.cx;
    let height = calendar.size.cy;
    height -= calendar.timeDiv.bounds.bottom - calendar.timeDiv.bounds.top;
    let yearButtonHeight = height - top;
    if (yearButtonHeight < 1) {
        yearButtonHeight = 1;
    }
    let toY = 0;
    let yearButtons = [];
    if (yearDiv.aDirection == 1) {
        toY = yearButtonHeight * yearDiv.aTick / yearDiv.aTotalTick;
        if (state == 1) {
            thisStartYear = nextStartYear;
            lastStartYear = thisStartYear - 12;
            nextStartYear = thisStartYear + 12;
        }
    }
    else if (yearDiv.aDirection == 2) {
        toY = -yearButtonHeight * yearDiv.aTick / yearDiv.aTotalTick;
        if (state == 1) {
            thisStartYear = lastStartYear;
            lastStartYear = thisStartYear - 12;
            nextStartYear = thisStartYear + 12;
        }
    }
    if (state == 0) {
        yearButtons = yearDiv.yearButtons;
    }
    else if (state == 1) {
        yearButtons = yearDiv.yearButtonsAm;
    }
    let dheight = yearButtonHeight / 3;
    let buttonSize = yearDiv.yearButtons.length;
    for (let i = 0; i < buttonSize; i++) {
        if (i == 8) {
            dheight = height - top;
        }
        let yearButton = yearButtons[i];
        yearButton.year = thisStartYear + i;
        let vOffSet = 0;
        if (state == 1) {
            if (yearDiv.aTick > 0) {
                yearButton.visible = true;
                if (yearDiv.aDirection == 1) {
                    vOffSet = toY - yearButtonHeight;
                }
                else if (yearDiv.aDirection == 2) {
                    vOffSet = toY + yearButtonHeight;
                }
            }
            else {
                yearButton.visible = false;
                continue;
            }
        }
        else {
            vOffSet = toY;
        }
        if ((i + 1) % 4 == 0) {
            let dp = new FCPoint(left, top + vOffSet);
            let ds = new FCSize(width - left, dheight);
            let bounds = new FCRect(dp.x, dp.y, dp.x + ds.cx, dp.y + ds.cy);
            yearButton.bounds = bounds;
            left = 0;
            if (i != 0 && i != buttonSize - 1) {
                top += dheight;
            }
        }
        else {
            let dp = new FCPoint(left, top + vOffSet);
            let ds = new FCSize(width / 4 + ((i + 1) % 4) % 2, dheight);
            let bounds = new FCRect(dp.x, dp.y, dp.x + ds.cx, dp.y + ds.cy);
            yearButton.bounds = bounds;
            left += ds.cx;
        }
    }
}
/*
* 选择开始年份
* yearDiv:年层
* startYear:开始年
*/
function selectStartYear(calendar, yearDiv, startYear) {
    if (yearDiv.startYear != startYear) {
        if (startYear > yearDiv.startYear) {
            yearDiv.aDirection = 1;
        }
        else {
            yearDiv.aDirection = 2;
        }
        if (calendar.useAnimation) {
            yearDiv.aTick = yearDiv.aTotalTick;
        }
        yearDiv.startYear = startYear;
    }
}
/*
* 选择年份
* calendar:日历
* monthDiv:月层
* year:年
*/
function selectYear(calendar, monthDiv, year) {
    if (monthDiv.year != year) {
        if (year > monthDiv.year) {
            monthDiv.aDirection = 1;
        }
        else {
            monthDiv.aDirection = 2;
        }
        if (calendar.useAnimation) {
            monthDiv.aTick = monthDiv.aTotalTick;
        }
        monthDiv.year = year;
    }
}
/*
* 选中日期
* calendar:日历
* dayDiv:日期层
* selectedDay:选中日
* lastDay:上一日
*/
function selectDay(calendar, dayDiv, selectedDay, lastDay) {
    let m = getYear(calendar, selectedDay.year).months.get(selectedDay.month);
    let thisMonth = getYear(calendar, lastDay.year).months.get(lastDay.month);
    if (m != thisMonth) {
        if (thisMonth.year * 12 + thisMonth.month > m.year * 12 + m.month) {
            dayDiv.aDirection = 2;
        }
        else {
            dayDiv.aDirection = 1;
        }
        let i = 0;
        let buttonSize = dayDiv.dayButtons.length;
        for (i = 0; i < buttonSize; i++) {
            let dayButton = dayDiv.dayButtons[i];
            if ((dayDiv.aDirection == 1 && dayButton.day == thisMonth.days.get(0))
                || (dayDiv.aDirection == 2 && dayButton.day == thisMonth.days.get(thisMonth.days.size - 1))) {
                dayDiv.aClickRowFrom = i / 7;
                if (i % 7 != 0) {
                    dayDiv.aClickRowFrom += 1;
                }
            }
        }
        resetDayDiv(calendar, dayDiv, 0);
        buttonSize = dayDiv.dayButtonsAm.length;
        for (i = 0; i < buttonSize; i++) {
            let dayFCButtonm = dayDiv.dayButtonsAm[i];
            if ((dayDiv.aDirection == 1 && dayFCButtonm.day == m.days.get(0))
                || (dayDiv.aDirection == 2 && dayFCButtonm.day == m.days.get(m.days.size - 1))) {
                dayDiv.aClickRowTo = i / 7;
                if (i % 7 != 0) {
                    dayDiv.aClickRowTo += 1;
                }
            }
        }
        if (calendar.useAnimation) {
            dayDiv.aTick = dayDiv.aTotalTick;
        }
    }
    else {
        let dayButtonsSize = dayDiv.dayButtons.length;
        for (let i = 0; i < dayButtonsSize; i++) {
            let dayButton = dayDiv.dayButtons[i];
            if (dayButton.day != selectedDay) {
                dayButton.selected = false;
            }
        }
    }
}
/*
* 更新日历的布局
* calendar:日历
*/
function updateCalendar(calendar) {
    calendar.headDiv.bounds = new FCRect(0, 0, calendar.size.cx, 80);
    if (calendar.mode == "day") {
        resetDayDiv(calendar, calendar.dayDiv, 0);
        resetDayDiv(calendar, calendar.dayDiv, 1);
    }
    else if (calendar.mode == "month") {
        resetMonthDiv(calendar, calendar.monthDiv, 0);
        resetMonthDiv(calendar, calendar.monthDiv, 1);
    }
    else if (calendar.mode == "year") {
        resetYearDiv(calendar, calendar.yearDiv, 0);
        resetYearDiv(calendar, calendar.yearDiv, 1);
    }
}
/*
* 绘制头部层
* calendar:日历
* headDiv:头部层
* paint:绘图对象
*/
function drawHeadDiv(calendar, headDiv, paint) {
    let bounds = headDiv.bounds;
    if (headDiv.backColor && headDiv.backColor != "none") {
        paint.fillRect(headDiv.backColor, bounds.left, bounds.top, bounds.right, bounds.bottom);
    }
    let weekStrings = new Array();
    weekStrings.push("周日");
    weekStrings.push("周一");
    weekStrings.push("周二");
    weekStrings.push("周三");
    weekStrings.push("周四");
    weekStrings.push("周五");
    weekStrings.push("周六");
    let w = bounds.right - bounds.left;
    let left = bounds.left;
    for (let i = 0; i < 7; i++) {
        let weekDaySize = paint.textSize(weekStrings[i], headDiv.weekFont);
        let textX = left + (w / 7) / 2 - weekDaySize.cx / 2;
        let textY = bounds.bottom - weekDaySize.cy - 2;
        paint.drawText(weekStrings[i], headDiv.textColor, headDiv.weekFont, textX, textY);
        left += w / 7;
    }
    let drawTitle = "";
    if (calendar.mode == "day") {
        drawTitle = calendar.selectedDay.year + "年" + calendar.selectedDay.month + "月";
    }
    else if (calendar.mode == "month") {
        drawTitle = calendar.monthDiv.year + "年";
    }
    else {
        drawTitle = calendar.yearDiv.startYear + "年-" + (calendar.yearDiv.startYear + 11) + "年";
    }
    let tSize = paint.textSize(drawTitle, headDiv.titleFont);
    paint.drawText(drawTitle, headDiv.textColor, headDiv.titleFont, bounds.left + (w - tSize.cx) / 2, 30);
    let tR = 10;
    //画左右三角
    paint.beginPath();
    paint.addLine(5, bounds.top + (bounds.bottom - bounds.top) / 2, 5 + tR * 2, bounds.top + (bounds.bottom - bounds.top) / 2 - tR);
    paint.addLine(5 + tR * 2, bounds.top + (bounds.bottom - bounds.top) / 2 - tR, 5 + tR * 2, bounds.top + (bounds.bottom - bounds.top) / 2 + tR);
    paint.addLine(5 + tR * 2, bounds.top + (bounds.bottom - bounds.top) / 2 + tR, 5, bounds.top + (bounds.bottom - bounds.top) / 2);
    paint.fillPath(headDiv.arrowColor);
    paint.closePath();
    paint.beginPath();
    paint.addLine(bounds.right - 5, bounds.top + (bounds.bottom - bounds.top) / 2, bounds.right - 5 - tR * 2, bounds.top + (bounds.bottom - bounds.top) / 2 - tR);
    paint.addLine(bounds.right - 5 - tR * 2, bounds.top + (bounds.bottom - bounds.top) / 2 - tR, bounds.right - 5 - tR * 2, bounds.top + (bounds.bottom - bounds.top) / 2 + tR);
    paint.addLine(bounds.right - 5 - tR * 2, bounds.top + (bounds.bottom - bounds.top) / 2 + tR, bounds.right - 5, bounds.top + (bounds.bottom - bounds.top) / 2);
    paint.fillPath(headDiv.arrowColor);
    paint.closePath();
}
/*
* 绘制日的按钮
* calendar:日历
* dayButton:日期按钮
* paint:绘图对象
*/
function drawDayButton(calendar, dayButton, paint) {
    if (dayButton.day) {
        let bounds = dayButton.bounds;
        let text = dayButton.day.day.toString();
        let tSize = paint.textSize(text, dayButton.font);
        if (dayButton.backColor && dayButton.backColor != "none") {
            paint.fillRect(dayButton.backColor, bounds.left + 2, bounds.top + 2, bounds.right - 2, bounds.bottom - 2);
        }
        if (dayButton.inThisMonth) {
            paint.drawText(text, dayButton.textColor, dayButton.font, bounds.left + 5, bounds.top + 7);
        }
        else {
            paint.drawText(text, dayButton.textColor2, dayButton.font, bounds.left + 5, bounds.top + 7);
        }
        if (dayButton.borderColor && dayButton.borderColor != "none") {
            paint.drawRect(dayButton.borderColor, 1, null, bounds.left + 2, bounds.top + 2, bounds.right - 2, bounds.bottom - 2);
        }
    }
}
/*
* 绘制月的按钮
* calendar:日历
* monthButton:月按钮
* paint:绘图对象
*/
function drawMonthButton(calendar, monthButton, paint) {
    let bounds = monthButton.bounds;
    let text = getMonthStr(monthButton.month);
    let tSize = paint.textSize(text, monthButton.font);
    if (monthButton.backColor && monthButton.backColor != "none") {
        paint.fillRect(monthButton.backColor, bounds.left + 2, bounds.top + 2, bounds.right - 2, bounds.bottom - 2);
    }
    paint.drawText(text, monthButton.textColor, monthButton.font, bounds.left + 5, bounds.top + 7);
    if (monthButton.borderColor && monthButton.borderColor != "none") {
        paint.drawRect(monthButton.borderColor, 1, null, bounds.left + 2, bounds.top + 2, bounds.right - 2, bounds.bottom - 2);
    }
}
/*
* 绘制年的按钮
* calendar:日历
* yearButton:年按钮
* paint:绘图对象
*/
function drawYearButton(calendar, yearButton, paint) {
    let bounds = yearButton.bounds;
    let text = yearButton.year.toString();
    let tSize = paint.textSize(text, yearButton.font);
    if (yearButton.backColor && yearButton.backColor != "none") {
        paint.fillRect(yearButton.backColor, bounds.left + 2, bounds.top + 2, bounds.right - 2, bounds.bottom - 2);
    }
    paint.drawText(text, yearButton.textColor, yearButton.font, bounds.left + 5, bounds.top + 7);
    if (yearButton.borderColor && yearButton.borderColor != "none") {
        paint.drawRect(yearButton.borderColor, 1, null, bounds.left + 2, bounds.top + 2, bounds.right - 2, bounds.bottom - 2);
    }
}
/*
* 绘制日历
* calendar:日历
* paint:绘图对象
*/
function drawCalendar(calendar, paint) {
    if (calendar.backColor && calendar.backColor != "none") {
        paint.fillRect(calendar.backColor, 0, 0, calendar.size.cx, calendar.size.cy);
    }
    if (calendar.mode == "day") {
        let dayButtonsSize = calendar.dayDiv.dayButtons.length;
        for (let i = 0; i < dayButtonsSize; i++) {
            let dayButton = calendar.dayDiv.dayButtons[i];
            if (dayButton.visible) {
                if (calendar.onPaintCalendarDayButton) {
                    calendar.onPaintCalendarDayButton(calendar, dayButton, paint);
                }
                else if (paint.onPaintCalendarDayButton) {
                    paint.onPaintCalendarDayButton(calendar, dayButton, paint);
                }
                else {
                    drawDayButton(calendar, dayButton, paint);
                }
            }
        }
        let dayFCButtonmSize = calendar.dayDiv.dayButtonsAm.length;
        for (let i = 0; i < dayFCButtonmSize; i++) {
            let dayButton = calendar.dayDiv.dayButtonsAm[i];
            if (dayButton.visible) {
                if (calendar.onPaintCalendarDayButton) {
                    calendar.onPaintCalendarDayButton(calendar, dayButton, paint);
                }
                else if (paint.onPaintCalendarDayButton) {
                    paint.onPaintCalendarDayButton(calendar, dayButton, paint);
                }
                else {
                    drawDayButton(calendar, dayButton, paint);
                }
            }
        }
    }
    else if (calendar.mode == "month") {
        let monthButtonsSize = calendar.monthDiv.monthButtons.length;
        for (let i = 0; i < monthButtonsSize; i++) {
            let monthButton = calendar.monthDiv.monthButtons[i];
            if (monthButton.visible) {
                if (calendar.onPaintCalendarMonthButton) {
                    calendar.onPaintCalendarMonthButton(calendar, monthButton, paint);
                }
                else if (paint.onPaintCalendarMonthButton) {
                    paint.onPaintCalendarMonthButton(calendar, monthButton, paint);
                }
                else {
                    drawMonthButton(calendar, monthButton, paint);
                }
            }
        }
        let monthFCButtonmSize = calendar.monthDiv.monthButtonsAm.length;
        for (let i = 0; i < monthFCButtonmSize; i++) {
            let monthButton = calendar.monthDiv.monthButtonsAm[i];
            if (monthButton.visible) {
                if (calendar.onPaintCalendarMonthButton) {
                    calendar.onPaintCalendarMonthButton(calendar, monthButton, paint);
                }
                else if (paint.onPaintCalendarMonthButton) {
                    paint.onPaintCalendarMonthButton(calendar, monthButton, paint);
                }
                else {
                    drawMonthButton(calendar, monthButton, paint);
                }
            }
        }
    }
    else if (calendar.mode == "year") {
        let yearButtonsSize = calendar.yearDiv.yearButtons.length;
        for (let i = 0; i < yearButtonsSize; i++) {
            let yearButton = calendar.yearDiv.yearButtons[i];
            if (yearButton.visible) {
                if (calendar.onPaintCalendarYearButton) {
                    calendar.onPaintCalendarYearButton(calendar, yearButton, paint);
                }
                else if (paint.onPaintCalendarYearButton) {
                    paint.onPaintCalendarYearButton(calendar, yearButton, paint);
                }
                else {
                    drawYearButton(calendar, yearButton, paint);
                }
            }
        }
        let yearFCButtonmSize = calendar.yearDiv.yearButtonsAm.length;
        for (let i = 0; i < yearFCButtonmSize; i++) {
            let yearButton = calendar.yearDiv.yearButtonsAm[i];
            if (yearButton.visible) {
                if (calendar.onPaintCalendarYearButton) {
                    calendar.onPaintCalendarYearButton(calendar, yearButton, paint);
                }
                else if (paint.onPaintCalendarYearButton) {
                    paint.onPaintCalendarYearButton(calendar, yearButton, paint);
                }
                else {
                    drawYearButton(calendar, yearButton, paint);
                }
            }
        }
    }
    if (calendar.onPaintCalendarHeadDiv) {
        calendar.onPaintCalendarHeadDiv(calendar, calendar.headDiv, paint);
    }
    else if (paint.onPaintCalendarHeadDiv) {
        paint.onPaintCalendarHeadDiv(calendar, calendar.headDiv, paint);
    }
    else {
        drawHeadDiv(calendar, calendar.headDiv, paint);
    }
    if (calendar.borderColor && calendar.borderColor != "none") {
        paint.drawRect(calendar.borderColor, 1, null, 0, 0, calendar.size.cx, calendar.size.cy);
    }
}
/*
* 点击日的按钮
* calendar:日历
* dayButton:日期按钮
* mp:坐标
*/
function clickDayButton(calendar, dayButton, mp) {
    let lastDay = calendar.selectedDay;
    calendar.selectedDay = dayButton.day;
    selectDay(calendar, calendar.dayDiv, calendar.selectedDay, lastDay);
    updateCalendar(calendar);
    if (calendar.paint) {
        invalidateView(calendar);
    }
}
/*
* 点击月的按钮
* calendar:日历
* monthButton:月按钮
* mp:坐标
*/
function clickMonthButton(calendar, monthButton, mp) {
    let month = getYear(calendar, monthButton.year).months.get(monthButton.month);
    calendar.mode = "day";
    let lastDay = calendar.selectedDay;
    calendar.selectedDay = month.days.get(1);
    selectDay(calendar, calendar.dayDiv, calendar.selectedDay, lastDay);
    updateCalendar(calendar);
    if (calendar.paint) {
        invalidateView(calendar);
    }
}
/*
* 点击年的按钮
* calendar:日历
* yearButton:年按钮
* mp:坐标
*/
function clickYearButton(calendar, yearButton, mp) {
    calendar.mode = "month";
    selectYear(calendar, calendar.monthDiv, yearButton.year);
    updateCalendar(calendar);
    if (calendar.paint) {
        invalidateView(calendar);
    }
}
/*
* 点击左侧的按钮
* calendar:日历
* headDiv:头部层
* mp:坐标
*/
function clickLastButton(calendar, headDiv, mp) {
    if (calendar.mode == "day") {
        let lastMonth = getLastMonth(calendar, calendar.selectedDay.year, calendar.selectedDay.month);
        let lastDay = calendar.selectedDay;
        calendar.selectedDay = lastMonth.days.get(1);
        selectDay(calendar, calendar.dayDiv, calendar.selectedDay, lastDay);
        updateCalendar(calendar);
        if (calendar.paint) {
            invalidateView(calendar);
        }
    }
    else if (calendar.mode == "month") {
        let year = calendar.monthDiv.year;
        year -= 1;
        selectYear(calendar, calendar.monthDiv, year);
        updateCalendar(calendar);
        if (calendar.paint) {
            invalidateView(calendar);
        }
    }
    else if (calendar.mode == "year") {
        let year = calendar.yearDiv.startYear;
        year -= 12;
        selectStartYear(calendar, calendar.yearDiv, year);
        updateCalendar(calendar);
        if (calendar.paint) {
            invalidateView(calendar);
        }
    }
}
/*
* 点击右侧的按钮
* calendar:日历
* headDiv:头部层
* mp:坐标
*/
function clickNextButton(calendar, headDiv, mp) {
    if (calendar.mode == "day") {
        let nextMonth = getNextMonth(calendar, calendar.selectedDay.year, calendar.selectedDay.month);
        let lastDay = calendar.selectedDay;
        calendar.selectedDay = nextMonth.days.get(1);
        selectDay(calendar, calendar.dayDiv, calendar.selectedDay, lastDay);
        updateCalendar(calendar);
        if (calendar.paint) {
            invalidateView(calendar);
        }
    }
    else if (calendar.mode == "month") {
        let year = calendar.monthDiv.year;
        year += 1;
        selectYear(calendar, calendar.monthDiv, year);
        updateCalendar(calendar);
        if (calendar.paint) {
            invalidateView(calendar);
        }
    }
    else if (calendar.mode == "year") {
        let year = calendar.yearDiv.startYear;
        year += 12;
        selectStartYear(calendar, calendar.yearDiv, year);
        updateCalendar(calendar);
        if (calendar.paint) {
            invalidateView(calendar);
        }
    }
}
/*
* 改变模式的按钮
* calendar:日历
* headDiv:头部层
* mp:坐标
*/
function clickModeButton(calendar, headDiv, mp) {
    if (calendar.mode == "day") {
        calendar.mode = "month";
        calendar.monthDiv.month = calendar.selectedDay.month;
        calendar.monthDiv.year = calendar.selectedDay.year;
        updateCalendar(calendar);
        if (calendar.paint) {
            invalidateView(calendar);
        }
    }
    else if (calendar.mode == "month") {
        calendar.mode = "year";
        selectStartYear(calendar, calendar.yearDiv, calendar.monthDiv.year);
        updateCalendar(calendar);
        if (calendar.paint) {
            invalidateView(calendar);
        }
    }
}
/*
* 点击日历
* calendar:日历
* mp:坐标
*/
function clickCalendar(calendar, mp) {
    let headBounds = calendar.headDiv.bounds;
    if (mp.x >= headBounds.left && mp.x <= headBounds.right && mp.y >= headBounds.top && mp.y <= headBounds.bottom) {
        let tR = 10;
        if (mp.x < headBounds.left + tR * 3) {
            clickLastButton(calendar, calendar.headDiv, mp);
            return;
        }
        else if (mp.x > headBounds.right - tR * 3) {
            clickNextButton(calendar, calendar.headDiv, mp);
            return;
        }
        else {
            clickModeButton(calendar, calendar.headDiv, mp);
            return;
        }
    }
    if (calendar.mode == "day") {
        let dayButtonsSize = calendar.dayDiv.dayButtons.length;
        for (let i = 0; i < dayButtonsSize; i++) {
            let dayButton = calendar.dayDiv.dayButtons[i];
            if (dayButton.visible) {
                let bounds = dayButton.bounds;
                if (mp.x >= bounds.left && mp.x <= bounds.right && mp.y >= bounds.top && mp.y <= bounds.bottom) {
                    clickDayButton(calendar, dayButton, mp);
                    return;
                }
            }
        }
    }
    else if (calendar.mode == "month") {
        let monthButtonsSize = calendar.monthDiv.monthButtons.length;
        for (let i = 0; i < monthButtonsSize; i++) {
            let monthButton = calendar.monthDiv.monthButtons[i];
            if (monthButton.visible) {
                let bounds = monthButton.bounds;
                if (mp.x >= bounds.left && mp.x <= bounds.right && mp.y >= bounds.top && mp.y <= bounds.bottom) {
                    clickMonthButton(calendar, monthButton, mp);
                    return;
                }
            }
        }
    }
    else if (calendar.mode == "year") {
        let yearButtonsSize = calendar.yearDiv.yearButtons.length;
        for (let i = 0; i < yearButtonsSize; i++) {
            let yearButton = calendar.yearDiv.yearButtons[i];
            if (yearButton.visible) {
                let bounds = yearButton.bounds;
                if (mp.x >= bounds.left && mp.x <= bounds.right && mp.y >= bounds.top && mp.y <= bounds.bottom) {
                    clickYearButton(calendar, yearButton, mp);
                    return;
                }
            }
        }
    }
}
/*
* 绘制滚动条
* div:图层
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawDivScrollBar(div, paint, clipRect) {
    div.hScrollIsVisible = false;
    div.vScrollIsVisible = false;
    if (paint.isMobile) {
        if (paint.touchDownView == div) {
        }
        else if (g_dragScrollView_Div == div && g_scrollAddSpeed_Div != 0) {
        }
        else {
            return;
        }
    }
    //绘制滚动条
    if (div.showHScrollBar) {
        let contentWidth = getDivContentWidth(div);
        if (contentWidth > 0 && contentWidth > div.size.cx) {
            let sLeft = div.scrollH / contentWidth * div.size.cx;
            let sRight = (div.scrollH + div.size.cx) / contentWidth * div.size.cx;
            if (sRight - sLeft < div.scrollSize) {
                sRight = sLeft + div.scrollSize;
            }
            if (paint.touchMoveView == div && (div.hoverScrollHButton || div.downScrollHButton)) {
                paint.fillRect(div.scrollBarHoveredColor, sLeft, div.size.cy - div.scrollSize, sRight, div.size.cy);
            }
            else {
                paint.fillRect(div.scrollBarColor, sLeft, div.size.cy - div.scrollSize, sRight, div.size.cy);
            }
            div.hScrollIsVisible = true;
        }
    }
    if (div.showVScrollBar) {
        let contentHeight = getDivContentHeight(div);
        if (contentHeight > 0 && contentHeight > div.size.cy) {
            let sTop = div.scrollV / contentHeight * div.size.cy;
            let sBottom = sTop + (div.size.cy / contentHeight * div.size.cy);
            if (sBottom - sTop < div.scrollSize) {
                sBottom = sTop + div.scrollSize;
            }
            if (paint.touchMoveView == div && (div.hoverScrollVButton || div.downScrollVButton)) {
                paint.fillRect(div.scrollBarHoveredColor, div.size.cx - div.scrollSize, sTop, div.size.cx, sBottom);
            }
            else {
                paint.fillRect(div.scrollBarColor, div.size.cx - div.scrollSize, sTop, div.size.cx, sBottom);
            }
            div.vScrollIsVisible = true;
        }
    }
}
/*
* 获取内容的宽度
* div:图层
*/
function getDivContentWidth(div) {
    let cWidth = 0;
    if (div.views) {
        for (let i = 0; i < div.views.length; i++) {
            if (div.views[i].visible) {
                if (cWidth < div.views[i].location.x + div.views[i].size.cx) {
                    cWidth = div.views[i].location.x + div.views[i].size.cx;
                }
            }
        }
    }
    return cWidth;
}
/*
* 获取内容的高度
* div:图层
*/
function getDivContentHeight(div) {
    let cHeight = 0;
    if (div.views) {
        for (let i = 0; i < div.views.length; i++) {
            if (div.views[i].visible) {
                if (cHeight < div.views[i].location.y + div.views[i].size.cy) {
                    cHeight = div.views[i].location.y + div.views[i].size.cy;
                }
            }
        }
    }
    return cHeight;
}
/*
* 图层的鼠标移动方法
* div: 图层
* firstTouch:是否第一次触摸
* firstPoint:第一次触摸的坐标
* secondTouch:是否第二次触摸
* secondPoint:第二次触摸的坐标
*/
function touchMoveDiv(div, firstTouch, firstPoint, secondTouch, secondPoint) {
    div.hoverScrollHButton = false;
    div.hoverScrollVButton = false;
    let mp = firstPoint;
    if (firstTouch) {
        if (div.showHScrollBar || div.showVScrollBar) {
            if (div.downScrollHButton) {
                let contentWidth = getDivContentWidth(div);
                let subX = (mp.x - div.startPoint.x) / div.size.cx * contentWidth;
                let newScrollH = div.startScrollH + subX;
                if (newScrollH < 0) {
                    newScrollH = 0;
                }
                else if (newScrollH > contentWidth - div.size.cx) {
                    newScrollH = contentWidth - div.size.cx;
                }
                div.scrollH = newScrollH;
                div.paint.cancelClick = true;
                return;
            }
            else if (div.downScrollVButton) {
                let contentHeight = getDivContentHeight(div);
                let subY = (mp.y - div.startPoint.y) / div.size.cy * contentHeight;
                let newScrollV = div.startScrollV + subY;
                if (newScrollV < 0) {
                    newScrollV = 0;
                }
                else if (newScrollV > contentHeight - div.size.cy) {
                    newScrollV = contentHeight - div.size.cy;
                }
                div.scrollV = newScrollV;
                div.paint.cancelClick = true;
                return;
            }
        }
        if (div.allowDragScroll) {
            let contentWidth = getDivContentWidth(div);
            if (contentWidth > div.size.cx) {
                let subX = div.startPoint.x - mp.x;
                let newScrollH = div.startScrollH + subX;
                if (newScrollH < 0) {
                    newScrollH = 0;
                }
                else if (newScrollH > contentWidth - div.size.cx) {
                    newScrollH = contentWidth - div.size.cx;
                }
                div.scrollH = newScrollH;
                if (Math.abs(subX) > 5) {
                    div.paint.cancelClick = true;
                }
            }
            let contentHeight = getDivContentHeight(div);
            if (contentHeight > div.size.cy) {
                let subY = div.startPoint.y - mp.y;
                let newScrollV = div.startScrollV + subY;
                if (newScrollV < 0) {
                    newScrollV = 0;
                }
                else if (newScrollV > contentHeight - div.size.cy) {
                    newScrollV = contentHeight - div.size.cy;
                }
                div.scrollV = newScrollV;
                if (Math.abs(subY) > 5) {
                    div.paint.cancelClick = true;
                }
            }
        }
    }
    else {
        if (div.showHScrollBar) {
            let contentWidth = getDivContentWidth(div);
            if (contentWidth > 0 && contentWidth > div.size.cx) {
                let sLeft = div.scrollH / contentWidth * div.size.cx;
                let sRight = (div.scrollH + div.size.cx) / contentWidth * div.size.cx;
                if (sRight - sLeft < div.scrollSize) {
                    sRight = sLeft + div.scrollSize;
                }
                if (mp.x >= sLeft && mp.x <= sRight && mp.y >= div.size.cy - div.scrollSize && mp.y <= div.size.cy) {
                    div.hoverScrollHButton = true;
                    return;
                }
                else {
                    div.hoverScrollHButton = false;
                }
            }
        }
        if (div.showVScrollBar) {
            let contentHeight = getDivContentHeight(div);
            if (contentHeight > 0 && contentHeight > div.size.cy) {
                let sTop = div.scrollV / contentHeight * div.size.cy;
                let sBottom = (div.scrollV + div.size.cy) / contentHeight * div.size.cy;
                if (sBottom - sTop < div.scrollSize) {
                    sBottom = sTop + div.scrollSize;
                }
                if (mp.x >= div.size.cx - div.scrollSize && mp.x <= div.size.cx && mp.y >= sTop && mp.y <= sBottom) {
                    div.hoverScrollVButton = true;
                    return;
                }
                else {
                    div.hoverScrollVButton = false;
                }
            }
        }
    }
}
/*
* 图层的鼠标按下方法
* div: 图层
* firstTouch:是否第一次触摸
* firstPoint:第一次触摸的坐标
* secondTouch:是否第二次触摸
* secondPoint:第二次触摸的坐标
* clicks:点击次数
*/
function touchDownDiv(div, firstTouch, firstPoint, secondTouch, secondPoint, clicks) {
    let mp = firstPoint;
    div.touchDownTime = new Date().getTime();
    div.startPoint = mp;
    div.downScrollHButton = false;
    div.downScrollVButton = false;
    div.hoverScrollHButton = false;
    div.hoverScrollVButton = false;
    g_dragScrollView_Div = null;
    g_scrollAddSpeed_Div = 0;
    g_scrollDirection_Div = 0;
    if (div.showHScrollBar) {
        let contentWidth = getDivContentWidth(div);
        if (contentWidth > 0 && contentWidth > div.size.cx) {
            let sLeft = div.scrollH / contentWidth * div.size.cx;
            let sRight = (div.scrollH + div.size.cx) / contentWidth * div.size.cx;
            if (sRight - sLeft < div.scrollSize) {
                sRight = sLeft + div.scrollSize;
            }
            if (mp.x >= sLeft && mp.x <= sRight && mp.y >= div.size.cy - div.scrollSize && mp.y <= div.size.cy) {
                div.downScrollHButton = true;
                div.startScrollH = div.scrollH;
                return;
            }
        }
    }
    if (div.showVScrollBar) {
        let contentHeight = getDivContentHeight(div);
        if (contentHeight > 0 && contentHeight > div.size.cy) {
            let sTop = div.scrollV / contentHeight * div.size.cy;
            let sBottom = (div.scrollV + div.size.cy) / contentHeight * div.size.cy;
            if (sBottom - sTop < div.scrollSize) {
                sBottom = sTop + div.scrollSize;
            }
            if (mp.x >= div.size.cx - div.scrollSize && mp.x <= div.size.cx && mp.y >= sTop && mp.y <= sBottom) {
                div.downScrollVButton = true;
                div.startScrollV = div.scrollV;
                return;
            }
        }
    }
    if (div.allowDragScroll) {
        div.startScrollH = div.scrollH;
        div.startScrollV = div.scrollV;
    }
}
let g_dragScrollView_Div = null; //正在滚动的表格
let g_scrollAddSpeed_Div = 0; //滚动加速
let g_scrollDirection_Div = 0; //滚动方向
/*
* 检查拖动滚动
*/
function checkDragScroll_Div() {
    if (g_dragScrollView_Div) {
        let sub = Math.floor(g_scrollAddSpeed_Div / 10);
        if (sub == 0 && g_scrollAddSpeed_Div > 1) {
            sub = 1;
        }
        else if (sub == 0 && g_scrollAddSpeed_Div < -1) {
            sub = -1;
        }
        g_scrollAddSpeed_Div -= sub;
        if (Math.abs(sub) <= 1) {
            let viewCache = g_dragScrollView_Div;
            g_scrollAddSpeed_Div = 0;
            g_dragScrollView_Div = null;
            if (viewCache.paint) {
                invalidateView(viewCache);
            }
        }
        else {
            let oldScrollV = Math.floor(g_dragScrollView_Div.scrollV + g_scrollAddSpeed_Div);
            let oldScrollH = Math.floor(g_dragScrollView_Div.scrollH + g_scrollAddSpeed_Div);
            if (g_scrollDirection_Div == 0) {
                let contentHeight = getDivContentHeight(g_dragScrollView_Div);
                if (contentHeight < g_dragScrollView_Div.size.cy) {
                    g_dragScrollView_Div.scrollV = 0;
                }
                else {
                    if (oldScrollV < 0) {
                        oldScrollV = 0;
                    }
                    else if (oldScrollV > contentHeight - g_dragScrollView_Div.size.cy) {
                        oldScrollV = contentHeight - g_dragScrollView_Div.size.cy;
                    }
                    g_dragScrollView_Div.scrollV = oldScrollV;
                }
            }
            else {
                let contentWidth = getDivContentWidth(g_dragScrollView_Div);
                if (contentWidth < g_dragScrollView_Div.size.cx) {
                    g_dragScrollView_Div.scrollH = 0;
                }
                else {
                    if (oldScrollH < 0) {
                        oldScrollH = 0;
                    }
                    else if (oldScrollH > contentWidth - g_dragScrollView_Div.size.cx) {
                        oldScrollH = contentWidth - g_dragScrollView_Div.size.cx;
                    }
                    g_dragScrollView_Div.scrollH = oldScrollH;
                }
            }
            if (g_dragScrollView_Div.paint) {
                invalidateView(g_dragScrollView_Div);
            }
        }
    }
}
/*
 * 更新滚动
 */
function updateScroll() {
    checkDragScroll_Div();
    checkGridDragScroll();
    checkTabPageAnimation();
    checkDragScroll_Tree();
    if (focusingTextBox != null) {
        focusingTextBox.focus();
        focusingTextBox = null;
    }
}
;
setInterval(updateScroll, 20);
/*
* 图层的鼠标抬起方法
* div: 图层
* firstTouch:是否第一次触摸
* firstPoint:第一次触摸的坐标
* secondTouch:是否第二次触摸
* secondPoint:第二次触摸的坐标
* clicks:点击次数
*/
function touchUpDiv(div, firstTouch, firstPoint, secondTouch, secondPoint, clicks) {
    div.hoverScrollHButton = false;
    div.hoverScrollVButton = false;
    if (firstTouch && firstPoint && div.startPoint && !div.downScrollHButton && !div.downScrollVButton) {
        if (div.allowDragScroll) {
            let touchUpTime = new Date().getTime();
            let diff = touchUpTime - div.touchDownTime;
            //加速滚动
            if (diff < 250) {
                let sub1 = 100 * ((Math.abs(firstPoint.y - div.startPoint.y)) / 20) / diff * 10;
                let sub2 = 100 * ((Math.abs(firstPoint.x - div.startPoint.x)) / 20) / diff * 10;
                if ("A:" + sub1 != "A:NaN" && "A:" + sub2 != "A:NaN") {
                    if (Math.abs(sub1) > Math.abs(sub2)) {
                        if (firstPoint.y < div.startPoint.y) {
                            g_scrollAddSpeed_Div += sub1;
                        }
                        else {
                            g_scrollAddSpeed_Div -= sub1;
                        }
                        g_scrollDirection_Div = 0;
                    }
                    else {
                        if (firstPoint.x < div.startPoint.x) {
                            g_scrollAddSpeed_Div += sub2;
                        }
                        else {
                            g_scrollAddSpeed_Div -= sub2;
                        }
                        g_scrollDirection_Div = 1;
                    }
                    g_dragScrollView_Div = div;
                    if (Math.abs(g_scrollAddSpeed_Div) > 0) {
                        div.paint.cancelClick = true;
                    }
                }
            }
        }
    }
    div.downScrollHButton = false;
    div.downScrollVButton = false;
}
/*
* 图层的鼠标滚轮方法
* div:图层
* delta:滚轮值
*/
function touchWheelDiv(div, delta) {
    let oldScrollV = div.scrollV;
    if (delta < 0) {
        oldScrollV -= 20;
    }
    else if (delta > 0) {
        oldScrollV += 20;
    }
    let contentHeight = getDivContentHeight(div);
    if (contentHeight < div.size.cy) {
        div.scrollV = 0;
    }
    else {
        if (oldScrollV < 0) {
            oldScrollV = 0;
        }
        else if (oldScrollV > contentHeight - div.size.cy) {
            oldScrollV = contentHeight - div.size.cy;
        }
        div.scrollV = oldScrollV;
    }
}
/*
* 重绘图层
* div:视图
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawDiv(div, paint, clipRect) {
    if (div.backColor && div.backColor != "none") {
        paint.fillRoundRect(div.backColor, 0, 0, div.size.cx, div.size.cy, div.cornerRadius);
    }
}
/*
* 重绘图层边线
* div:视图
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawDivBorder(div, paint, clipRect) {
    if (div.borderColor && div.borderColor != "none") {
        paint.drawRoundRect(div.borderColor, div.borderWidth, null, 0, 0, div.size.cx, div.size.cy, div.cornerRadius);
    }
}
let g_dragScrollView_Grid = null; //正在滚动的表格
let g_scrollAddSpeed_Grid = 0; //滚动加速
let g_scrollDirection_Grid = 0; //滚动方向
/*
 * 快速添加表格列
 * grid:表格
 * columns:列名集合
 */
function fastAddGridColumns(grid, columns) {
    let columnsSize = columns.length;
    for (let i = 0; i < columnsSize; i++) {
        let gridColumn = new FCGridColumn();
        gridColumn.text = columns[i];
        grid.columns.push(gridColumn);
    }
}
/*
 * 快速添加表格行
 * grid:表格
 * datas:数据集合
 */
function fastAddGridRow(grid, datas) {
    let gridRow = new FCGridRow();
    let datasSize = datas.length;
    for (let i = 0; i < datasSize; i++) {
        let gridCell = new FCGridCell();
        gridCell.value = datas[i];
        gridRow.cells.push(gridCell);
    }
    return gridRow;
}
/*
 * 添加视图到单元格
 * view:视图
 * cell:单元格
 * grid:表格
 */
function addViewToGridCell(view, cell, grid) {
    view.displayOffset = false;
    view.visible = false;
    cell.view = view;
    addViewToParent(view, grid);
}
/*
* 绘制单元格
* grid:表格
* row:行
* column:列
* cell:单元格
* paint:绘图对象
* left:左侧坐标
* top:上方坐标
* right:右侧坐标
* bottom:下方坐标
*/
function drawGridCell(grid, row, column, cell, paint, left, top, right, bottom) {
    if (cell.backColor && cell.backColor != "none") {
        paint.fillRect(cell.backColor, left, top, right, bottom);
    }
    if (row.selected) {
        if (grid.selectedRowColor && grid.selectedRowColor != "none") {
            paint.fillRect(grid.selectedRowColor, left, top, right, bottom);
        }
    }
    if (cell.borderColor && cell.borderColor != "none") {
        paint.drawRect(cell.borderColor, 1, null, left, top, right, bottom);
    }
    let showText = cell.value;
    if (column.colType == "double") {
        if (cell.digit >= 0) {
            let numValue = Number(showText);
            showText = numValue.toFixed(cell.digit);
        }
    }
    else {
        if (!showText) {
            return;
        }
    }
    let tSize = paint.textSize(showText, cell.font);
    if (tSize.cx > column.width) {
        paint.drawTextAutoEllipsis(showText, cell.textColor, cell.font, left + 2, top + grid.rowHeight / 2 - tSize.cy / 2, left + 2 + column.width, top + grid.rowHeight / 2 - tSize.cy / 2);
    }
    else {
        if (column.cellAlign == "left") {
            paint.drawText(showText, cell.textColor, cell.font, left + 2, top + grid.rowHeight / 2 - tSize.cy / 2);
        }
        else if (column.cellAlign == "center") {
            paint.drawText(showText, cell.textColor, cell.font, left + (right - left - tSize.cx) / 2, top + grid.rowHeight / 2 - tSize.cy / 2);
        }
        else if (column.cellAlign == "right") {
            paint.drawText(showText, cell.textColor, cell.font, right - tSize.cx, top + grid.rowHeight / 2 - tSize.cy / 2);
        }
    }
}
/*
* 绘制列
* grid:表格
* column:列
* paint:绘图对象
* left:左侧坐标
* top:上方坐标
* right:右侧坐标
* bottom:下方坐标
*/
function drawGridColumn(grid, column, paint, left, top, right, bottom) {
    let tSize = paint.textSize(column.text, column.font);
    if (column.backColor && column.backColor != "none") {
        paint.fillRect(column.backColor, left, top, right, bottom);
    }
    if (column.borderColor && column.borderColor != "none") {
        paint.drawRect(column.borderColor, 1, null, left, top, right, bottom);
    }
    paint.drawText(column.text, column.textColor, column.font, left + (column.width - tSize.cx) / 2, top + grid.headerHeight / 2 - tSize.cy / 2);
    if (column.sort == "asc") {
        paint.beginPath();
        let cR = (bottom - top) / 4;
        let oX = right - cR * 2, oY = top + (bottom - top) / 2;
        paint.addLine(oX, oY - cR, oX - cR, oY + cR);
        paint.addLine(oX - cR, oY + cR, oX + cR, oY + cR);
        paint.addLine(oX + cR, oY + cR, oX, oY - cR);
        paint.fillPath(column.textColor);
        paint.closePath();
    }
    else if (column.sort == "desc") {
        paint.beginPath();
        let cR = (bottom - top) / 4;
        let oX = right - cR * 2, oY = top + (bottom - top) / 2;
        paint.addLine(oX, oY + cR, oX - cR, oY - cR);
        paint.addLine(oX - cR, oY - cR, oX + cR, oY - cR);
        paint.addLine(oX + cR, oY - cR, oX, oY + cR);
        paint.fillPath(column.textColor);
        paint.closePath();
    }
}
/*
* 绘制表格
* grid:表格
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawGrid(grid, paint, clipRect) {
    let cTop = -grid.scrollV + grid.headerHeight;
    //绘制行
    let colLeft = 0;
    for (let i = 0; i < grid.views.length; i++) {
        grid.views[i].visible = false;
    }
    for (let i = 0; i < grid.columns.length; i++) {
        if (grid.columns[i].widthStr.length > 0) {
            let newWidthStr = grid.columns[i].widthStr.replace("%", "");
            grid.columns[i].width = Number(newWidthStr) * grid.size.cx / 100;
        }
        let colRect = new FCRect(colLeft, 0, colLeft + grid.columns[i].width, grid.headerHeight);
        grid.columns[i].bounds = colRect;
        grid.columns[i].index = i;
        colLeft += grid.columns[i].width;
    }
    for (let i = 0; i < grid.rows.length; i++) {
        let row = grid.rows[i];
        row.index = i;
        if (row.visible) {
            let rTop = cTop, rBottom = cTop + grid.rowHeight;
            if (rBottom >= 0 && cTop <= grid.size.cy) {
                for (let j = 0; j < row.cells.length; j++) {
                    let cell = row.cells[j];
                    let gridColumn = cell.column;
                    if (!gridColumn) {
                        gridColumn = grid.columns[j];
                    }
                    if (gridColumn.visible) {
                        if (!gridColumn.frozen) {
                            let cellWidth = gridColumn.width;
                            let colSpan = cell.colSpan;
                            if (colSpan > 1) {
                                for (let n = 1; n < colSpan; n++) {
                                    let spanColumn = grid.columns[gridColumn.index + n];
                                    if (spanColumn && spanColumn.visible) {
                                        cellWidth += spanColumn.width;
                                    }
                                }
                            }
                            let cellHeight = grid.rowHeight;
                            let rowSpan = cell.rowSpan;
                            if (rowSpan > 1) {
                                for (let n = 1; n < rowSpan; n++) {
                                    let spanRow = grid.rows[i + n];
                                    if (spanRow && spanRow.visible) {
                                        cellHeight += grid.rowHeight;
                                    }
                                }
                            }
                            let cRect = new FCRect(gridColumn.bounds.left - grid.scrollH, rTop, gridColumn.bounds.left + cellWidth - grid.scrollH, rTop + cellHeight);
                            if (cRect.right >= 0 && cRect.left < grid.size.cx) {
                                if (grid.onPaintGridCell) {
                                    grid.onPaintGridCell(grid, row, gridColumn, cell, paint, cRect.left, cRect.top, cRect.right, cRect.bottom);
                                }
                                else if (paint.onPaintGridCell) {
                                    paint.onPaintGridCell(grid, row, gridColumn, cell, paint, cRect.left, cRect.top, cRect.right, cRect.bottom);
                                }
                                else {
                                    drawGridCell(grid, row, gridColumn, cell, paint, cRect.left, cRect.top, cRect.right, cRect.bottom);
                                }
                                if (cell.view) {
                                    cell.view.visible = true;
                                    cell.view.location = new FCPoint(cRect.left + grid.scrollH, cRect.top + grid.scrollV);
                                    cell.view.size = new FCSize(cRect.right - cRect.left, cRect.bottom - cRect.top);
                                }
                            }
                        }
                    }
                }
            }
            if (rBottom >= 0 && cTop <= grid.size.cy) {
                for (let j = 0; j < row.cells.length; j++) {
                    let cell = row.cells[j];
                    let gridColumn = cell.column;
                    if (!gridColumn) {
                        gridColumn = grid.columns[j];
                    }
                    if (gridColumn.visible) {
                        if (gridColumn.frozen) {
                            let cellWidth = gridColumn.width;
                            let colSpan = cell.colSpan;
                            if (colSpan > 1) {
                                for (let n = 1; n < colSpan; n++) {
                                    let spanColumn = grid.columns[gridColumn.index + n];
                                    if (spanColumn && spanColumn.visible) {
                                        cellWidth += spanColumn.width;
                                    }
                                }
                            }
                            let cellHeight = grid.rowHeight;
                            let rowSpan = cell.rowSpan;
                            if (rowSpan > 1) {
                                for (let n = 1; n < rowSpan; n++) {
                                    let spanRow = grid.rows[i + n];
                                    if (spanRow && spanRow.visible) {
                                        cellHeight += grid.rowHeight;
                                    }
                                }
                            }
                            let cRect = new FCRect(gridColumn.bounds.left, rTop, gridColumn.bounds.left + cellWidth, rTop + cellHeight);
                            if (cRect.right >= 0 && cRect.left < grid.size.cx) {
                                if (grid.onPaintGridCell) {
                                    grid.onPaintGridCell(grid, row, gridColumn, cell, paint, cRect.left, cRect.top, cRect.right, cRect.bottom);
                                }
                                else if (paint.onPaintGridCell) {
                                    paint.onPaintGridCell(grid, row, gridColumn, cell, paint, cRect.left, cRect.top, cRect.right, cRect.bottom);
                                }
                                else {
                                    drawGridCell(grid, row, gridColumn, cell, paint, cRect.left, cRect.top, cRect.right, cRect.bottom);
                                }
                                if (cell.view) {
                                    cell.view.visible = true;
                                    cell.view.location = new FCPoint(cRect.left + grid.scrollH, cRect.top + grid.scrollV);
                                    cell.view.size = new FCSize(cRect.right - cRect.left, cRect.bottom - cRect.top);
                                }
                            }
                        }
                    }
                }
            }
            if (cTop > grid.size.cy) {
                break;
            }
            cTop += grid.rowHeight;
        }
    }
}
/*
* 绘制表格的滚动条
* grid:表格
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawGridScrollBar(grid, paint, clipRect) {
    grid.hScrollIsVisible = false;
    grid.vScrollIsVisible = false;
    if (grid.headerHeight > 0) {
        let cLeft = -grid.scrollH;
        //绘制列
        for (let i = 0; i < grid.columns.length; i++) {
            let gridColumn = grid.columns[i];
            if (grid.columns[i].visible) {
                if (!gridColumn.frozen) {
                    if (grid.onPaintGridColumn) {
                        grid.onPaintGridColumn(grid, grid.columns[i], paint, cLeft, 0, cLeft + gridColumn.width, grid.headerHeight);
                    }
                    else if (paint.onPaintGridColumn) {
                        paint.onPaintGridColumn(grid, grid.columns[i], paint, cLeft, 0, cLeft + gridColumn.width, grid.headerHeight);
                    }
                    else {
                        drawGridColumn(grid, grid.columns[i], paint, cLeft, 0, cLeft + gridColumn.width, grid.headerHeight);
                    }
                }
                cLeft += gridColumn.width;
            }
        }
        cLeft = 0;
        for (let i = 0; i < grid.columns.length; i++) {
            let gridColumn = grid.columns[i];
            if (grid.columns[i].visible) {
                if (gridColumn.frozen) {
                    if (grid.onPaintGridColumn) {
                        grid.onPaintGridColumn(grid, grid.columns[i], paint, cLeft, 0, cLeft + gridColumn.width, grid.headerHeight);
                    }
                    else if (paint.onPaintGridColumn) {
                        paint.onPaintGridColumn(grid, grid.columns[i], paint, cLeft, 0, cLeft + gridColumn.width, grid.headerHeight);
                    }
                    else {
                        drawGridColumn(grid, grid.columns[i], paint, cLeft, 0, cLeft + gridColumn.width, grid.headerHeight);
                    }
                }
                cLeft += gridColumn.width;
            }
        }
    }
    if (paint.isMobile) {
        if (paint.touchDownView == grid) {
        }
        else if (g_dragScrollView_Grid == grid && g_scrollAddSpeed_Grid != 0) {
        }
        else {
            return;
        }
    }
    if (grid.showHScrollBar) {
        let contentWidth = getGridContentWidth(grid);
        if (contentWidth > 0 && contentWidth > grid.size.cx) {
            let sLeft = grid.scrollH / contentWidth * grid.size.cx;
            let sRight = (grid.scrollH + grid.size.cx) / contentWidth * grid.size.cx;
            if (sRight - sLeft < grid.scrollSize) {
                sRight = sLeft + grid.scrollSize;
            }
            if (paint.touchMoveView == grid && (grid.hoverScrollHButton || grid.downScrollHButton)) {
                paint.fillRect(grid.scrollBarHoveredColor, sLeft, grid.size.cy - grid.scrollSize, sRight, grid.size.cy);
            }
            else {
                paint.fillRect(grid.scrollBarColor, sLeft, grid.size.cy - grid.scrollSize, sRight, grid.size.cy);
            }
            grid.hScrollIsVisible = true;
        }
    }
    if (grid.showVScrollBar) {
        let contentHeight = getGridContentHeight(grid);
        if (contentHeight > 0 && contentHeight > grid.size.cy - grid.headerHeight) {
            let sTop = grid.headerHeight + grid.scrollV / contentHeight * (grid.size.cy - grid.headerHeight - grid.scrollSize);
            let sBottom = sTop + ((grid.size.cy - grid.headerHeight - grid.scrollSize)) / contentHeight * (grid.size.cy - grid.headerHeight - grid.scrollSize);
            if (sBottom - sTop < grid.scrollSize) {
                sBottom = sTop + grid.scrollSize;
            }
            if (paint.touchMoveView == grid && (grid.hoverScrollVButton || grid.downScrollVButton)) {
                paint.fillRect(grid.scrollBarHoveredColor, grid.size.cx - grid.scrollSize, sTop, grid.size.cx, sBottom);
            }
            else {
                paint.fillRect(grid.scrollBarColor, grid.size.cx - grid.scrollSize, sTop, grid.size.cx, sBottom);
            }
            grid.vScrollIsVisible = true;
        }
    }
}
/*
* 获取内容的宽度
* grid:表格
*/
function getGridContentWidth(grid) {
    let cWidth = 0;
    for (let i = 0; i < grid.columns.length; i++) {
        if (grid.columns[i].visible) {
            cWidth += grid.columns[i].width;
        }
    }
    return cWidth;
}
/*
* 获取内容的高度
* grid:表格
*/
function getGridContentHeight(grid) {
    let cHeight = 0;
    for (let i = 0; i < grid.rows.length; i++) {
        if (grid.rows[i].visible) {
            cHeight += grid.rowHeight;
        }
    }
    return cHeight;
}
/*
* 表格的鼠标移动方法
* grid: 表格
* firstTouch:是否第一次触摸
* firstPoint:第一次触摸的坐标
* secondTouch:是否第二次触摸
* secondPoint:第二次触摸的坐标
*/
function touchMoveGrid(grid, firstTouch, firstPoint, secondTouch, secondPoint) {
    grid.hoverScrollHButton = false;
    grid.hoverScrollVButton = false;
    let mp = firstPoint;
    if (firstTouch) {
        if (grid.paint.resizeColumnState != 0) {
            let gridColumn = grid.columns[grid.paint.resizeColumnIndex];
            let newWidth = grid.paint.resizeColumnBeginWidth + (mp.x - grid.startPoint.x);
            if (newWidth > 10) {
                gridColumn.width = newWidth;
            }
            return;
        }
        if (grid.showHScrollBar || grid.showVScrollBar) {
            if (grid.downScrollHButton) {
                let contentWidth = getGridContentWidth(grid);
                let subX = (mp.x - grid.startPoint.x) / grid.size.cx * contentWidth;
                let newScrollH = grid.startScrollH + subX;
                if (newScrollH < 0) {
                    newScrollH = 0;
                }
                else if (newScrollH > contentWidth - grid.size.cx) {
                    newScrollH = contentWidth - grid.size.cx;
                }
                grid.scrollH = newScrollH;
                grid.paint.cancelClick = true;
                return;
            }
            else if (grid.downScrollVButton) {
                let contentHeight = getGridContentHeight(grid);
                let subY = (mp.y - grid.startPoint.y) / (grid.size.cy - grid.headerHeight - grid.scrollSize) * contentHeight;
                let newScrollV = grid.startScrollV + subY;
                if (newScrollV < 0) {
                    newScrollV = 0;
                }
                else if (newScrollV > contentHeight - (grid.size.cy - grid.headerHeight - grid.scrollSize)) {
                    newScrollV = contentHeight - (grid.size.cy - grid.headerHeight - grid.scrollSize);
                }
                grid.scrollV = newScrollV;
                grid.paint.cancelClick = true;
                return;
            }
        }
        if (grid.allowDragScroll) {
            let contentWidth = getGridContentWidth(grid);
            if (contentWidth > grid.size.cx - grid.scrollSize) {
                let subX = grid.startPoint.x - mp.x;
                let newScrollH = grid.startScrollH + subX;
                if (newScrollH < 0) {
                    newScrollH = 0;
                }
                else if (newScrollH > contentWidth - grid.size.cx) {
                    newScrollH = contentWidth - grid.size.cx;
                }
                grid.scrollH = newScrollH;
                if (Math.abs(subX) > 5) {
                    grid.paint.cancelClick = true;
                }
            }
            let contentHeight = getGridContentHeight(grid);
            if (contentHeight > grid.size.cy - grid.headerHeight - grid.scrollSize) {
                let subY = grid.startPoint.y - mp.y;
                let newScrollV = grid.startScrollV + subY;
                if (newScrollV < 0) {
                    newScrollV = 0;
                }
                else if (newScrollV > contentHeight - (grid.size.cy - grid.headerHeight - grid.scrollSize)) {
                    newScrollV = contentHeight - (grid.size.cy - grid.headerHeight - grid.scrollSize);
                }
                grid.scrollV = newScrollV;
                if (Math.abs(subY) > 5) {
                    grid.paint.cancelClick = true;
                }
            }
        }
    }
    else {
        if (grid.showHScrollBar) {
            let contentWidth = getGridContentWidth(grid);
            if (contentWidth > 0 && contentWidth > grid.size.cx - grid.scrollSize) {
                let sLeft = grid.scrollH / contentWidth * grid.size.cx;
                let sRight = (grid.scrollH + grid.size.cx) / contentWidth * grid.size.cx;
                if (sRight - sLeft < grid.scrollSize) {
                    sRight = sLeft + grid.scrollSize;
                }
                if (mp.x >= sLeft && mp.x <= sRight && mp.y >= grid.size.cy - grid.scrollSize && mp.y <= grid.size.cy) {
                    grid.hoverScrollHButton = true;
                    return;
                }
                else {
                    grid.hoverScrollHButton = false;
                }
            }
        }
        if (grid.showVScrollBar) {
            let contentHeight = getGridContentHeight(grid);
            if (contentHeight > 0 && contentHeight > grid.size.cy - grid.headerHeight - grid.scrollSize) {
                let sTop = grid.headerHeight + grid.scrollV / contentHeight * (grid.size.cy - grid.headerHeight - grid.scrollSize);
                let sBottom = grid.headerHeight + (grid.scrollV + (grid.size.cy - grid.headerHeight - grid.scrollSize)) / contentHeight * (grid.size.cy - grid.headerHeight - grid.scrollSize);
                if (sBottom - sTop < grid.scrollSize) {
                    sBottom = sTop + grid.scrollSize;
                }
                if (mp.x >= grid.size.cx - grid.scrollSize && mp.x <= grid.size.cx && mp.y >= sTop && mp.y <= sBottom) {
                    grid.hoverScrollVButton = true;
                    return;
                }
                else {
                    grid.hoverScrollVButton = false;
                }
            }
        }
    }
}
/*
* 表格的鼠标按下方法
* grid: 表格
* firstTouch:是否第一次触摸
* firstPoint:第一次触摸的坐标
* secondTouch:是否第二次触摸
* secondPoint:第二次触摸的坐标
* clicks:点击次数
*/
function touchDownGrid(grid, firstTouch, firstPoint, secondTouch, secondPoint, clicks) {
    let mp = firstPoint;
    grid.touchDownTime = new Date().getTime();
    grid.startPoint = mp;
    grid.downScrollHButton = false;
    grid.downScrollVButton = false;
    grid.hoverScrollHButton = false;
    grid.hoverScrollVButton = false;
    g_dragScrollView_Grid = null;
    g_scrollAddSpeed_Grid = 0;
    g_scrollDirection_Grid = 0;
    if (grid.showHScrollBar) {
        let contentWidth = getGridContentWidth(grid);
        if (contentWidth > 0 && contentWidth > grid.size.cx - grid.scrollSize) {
            let sLeft = grid.scrollH / contentWidth * grid.size.cx;
            let sRight = (grid.scrollH + grid.size.cx) / contentWidth * grid.size.cx;
            if (sRight - sLeft < grid.scrollSize) {
                sRight = sLeft + grid.scrollSize;
            }
            if (mp.x >= sLeft && mp.x <= sRight && mp.y >= grid.size.cy - grid.scrollSize && mp.y <= grid.size.cy) {
                grid.downScrollHButton = true;
                grid.startScrollH = grid.scrollH;
                return;
            }
        }
    }
    if (grid.showVScrollBar) {
        let contentHeight = getGridContentHeight(grid);
        if (contentHeight > 0 && contentHeight > grid.size.cy - grid.headerHeight - grid.scrollSize) {
            let sTop = grid.headerHeight + grid.scrollV / contentHeight * (grid.size.cy - grid.headerHeight - grid.scrollSize);
            let sBottom = grid.headerHeight + (grid.scrollV + (grid.size.cy - grid.headerHeight - grid.scrollSize)) / contentHeight * (grid.size.cy - grid.headerHeight - grid.scrollSize);
            if (sBottom - sTop < grid.scrollSize) {
                sBottom = sTop + grid.scrollSize;
            }
            if (mp.x >= grid.size.cx - grid.scrollSize && mp.x <= grid.size.cx && mp.y >= sTop && mp.y <= sBottom) {
                grid.downScrollVButton = true;
                grid.startScrollV = grid.scrollV;
                return;
            }
        }
    }
    if (grid.allowDragScroll) {
        grid.startScrollH = grid.scrollH;
        grid.startScrollV = grid.scrollV;
    }
    let colLeft = 0;
    for (let i = 0; i < grid.columns.length; i++) {
        let colRect = new FCRect(colLeft, 0, colLeft + grid.columns[i].width, grid.headerHeight);
        grid.columns[i].bounds = colRect;
        grid.columns[i].index = i;
        colLeft += grid.columns[i].width;
    }
    grid.paint.resizeColumnState = 0;
    grid.paint.resizeColumnBeginWidth = 0;
    if (grid.headerHeight > 0 && mp.y <= grid.headerHeight) {
        //绘制列
        for (let i = 0; i < grid.columns.length; i++) {
            let gridColumn = grid.columns[i];
            if (gridColumn.visible) {
                let bounds = gridColumn.bounds;
                if (mp.x >= bounds.left - grid.scrollH && mp.x <= bounds.right - grid.scrollH) {
                    if (gridColumn.index > 0 && mp.x < bounds.left + 5 - grid.scrollH) {
                        grid.paint.resizeColumnState = 1;
                        grid.paint.resizeColumnBeginWidth = grid.columns[gridColumn.index - 1].bounds.right - grid.columns[gridColumn.index - 1].bounds.left;
                        grid.paint.resizeColumnIndex = gridColumn.index - 1;
                        return;
                    }
                    else if (mp.x > bounds.right - 5 - grid.scrollH) {
                        grid.paint.resizeColumnState = 2;
                        grid.paint.resizeColumnBeginWidth = bounds.right - bounds.left;
                        grid.paint.resizeColumnIndex = gridColumn.index;
                        return;
                    }
                    break;
                }
            }
        }
    }
}
/*
* 表格的鼠标抬起方法
* grid: 表格
* firstTouch:是否第一次触摸
* firstPoint:第一次触摸的坐标
* secondTouch:是否第二次触摸
* secondPoint:第二次触摸的坐标
* clicks:点击次数
*/
function touchUpGrid(grid, firstTouch, firstPoint, secondTouch, secondPoint, clicks) {
    grid.hoverScrollHButton = false;
    grid.hoverScrollVButton = false;
    if (grid.paint.resizeColumnState != 0) {
        grid.paint.resizeColumnState = 0;
        return;
    }
    if (firstTouch && firstPoint && grid.startPoint && !grid.downScrollHButton && !grid.downScrollVButton) {
        if (grid.allowDragScroll) {
            let touchUpTime = new Date().getTime();
            let diff = touchUpTime - grid.touchDownTime;
            //加速滚动
            if (diff < 250) {
                let sub1 = 100 * ((Math.abs(firstPoint.y - grid.startPoint.y)) / 20) / diff * 10;
                let sub2 = 100 * ((Math.abs(firstPoint.x - grid.startPoint.x)) / 20) / diff * 10;
                if ("A:" + sub1 != "A:NaN" && "A:" + sub2 != "A:NaN") {
                    if (Math.abs(sub1) > Math.abs(sub2)) {
                        if (firstPoint.y < grid.startPoint.y) {
                            g_scrollAddSpeed_Grid += sub1;
                        }
                        else {
                            g_scrollAddSpeed_Grid -= sub1;
                        }
                        g_scrollDirection_Grid = 0;
                    }
                    else {
                        if (firstPoint.x < grid.startPoint.x) {
                            g_scrollAddSpeed_Grid += sub2;
                        }
                        else {
                            g_scrollAddSpeed_Grid -= sub2;
                        }
                        g_scrollDirection_Grid = 1;
                    }
                    if (Math.abs(g_scrollAddSpeed_Grid) > 0) {
                        grid.paint.cancelClick = true;
                    }
                    g_dragScrollView_Grid = grid;
                }
            }
        }
    }
    grid.downScrollHButton = false;
    grid.downScrollVButton = false;
    if (grid.paint.cancelClick) {
        return;
    }
    let cTop = -grid.scrollV + grid.headerHeight;
    //绘制行
    let colLeft = 0;
    for (let i = 0; i < grid.columns.length; i++) {
        let colRect = new FCRect(colLeft, 0, colLeft + grid.columns[i].width, grid.headerHeight);
        grid.columns[i].bounds = colRect;
        grid.columns[i].index = i;
        colLeft += grid.columns[i].width;
    }
    if (grid.headerHeight > 0 && firstPoint.y <= grid.headerHeight) {
        let cLeft = 0;
        //绘制列
        for (let i = 0; i < grid.columns.length; i++) {
            let gridColumn = grid.columns[i];
            if (grid.columns[i].visible) {
                if (gridColumn.frozen) {
                    if (firstPoint.x >= cLeft && firstPoint.x <= cLeft + gridColumn.width) {
                        for (let j = 0; j < grid.columns.length; j++) {
                            let tColumn = grid.columns[j];
                            if (tColumn == gridColumn) {
                                if (tColumn.allowSort) {
                                    if (tColumn.sort == "none" || tColumn.sort == "desc") {
                                        tColumn.sort = "asc";
                                        grid.rows.sort((m, n) => {
                                            if (m.cells.length > j && n.cells.length > j) {
                                                if (m.cells[j].value < n.cells[j].value) {
                                                    return -1;
                                                }
                                                else if (m.cells[j].value > n.cells[j].value) {
                                                    return 1;
                                                }
                                                else
                                                    return 0;
                                            }
                                            else {
                                                return 0;
                                            }
                                        });
                                    }
                                    else {
                                        tColumn.sort = "desc";
                                        grid.rows.sort((m, n) => {
                                            if (m.cells.length > j && n.cells.length > j) {
                                                if (m.cells[j].value > n.cells[j].value) {
                                                    return -1;
                                                }
                                                else if (m.cells[j].value < n.cells[j].value) {
                                                    return 1;
                                                }
                                                else
                                                    return 0;
                                            }
                                            else {
                                                return 0;
                                            }
                                        });
                                    }
                                }
                                else {
                                    tColumn.sort = "none";
                                }
                            }
                            else {
                                tColumn.sort = "none";
                            }
                        }
                        if (grid.onClickGridColumn) {
                            grid.onClickGridColumn(grid, gridColumn, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
                        }
                        else if (grid.paint && grid.paint.onClickGridColumn) {
                            grid.paint.onClickGridColumn(grid, gridColumn, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
                        }
                        return;
                    }
                }
                cLeft += gridColumn.width;
            }
        }
        cLeft = -grid.scrollH;
        for (let i = 0; i < grid.columns.length; i++) {
            let gridColumn = grid.columns[i];
            if (grid.columns[i].visible) {
                if (!gridColumn.frozen) {
                    if (firstPoint.x >= cLeft && firstPoint.x <= cLeft + gridColumn.width) {
                        for (let j = 0; j < grid.columns.length; j++) {
                            let tColumn = grid.columns[j];
                            if (tColumn == gridColumn) {
                                if (tColumn.allowSort) {
                                    if (tColumn.sort == "none" || tColumn.sort == "desc") {
                                        tColumn.sort = "asc";
                                        grid.rows.sort((m, n) => {
                                            if (m.cells.length > j && n.cells.length > j) {
                                                if (m.cells[j].value < n.cells[j].value) {
                                                    return -1;
                                                }
                                                else if (m.cells[j].value > n.cells[j].value) {
                                                    return 1;
                                                }
                                                else
                                                    return 0;
                                            }
                                            else {
                                                return 0;
                                            }
                                        });
                                    }
                                    else {
                                        tColumn.sort = "desc";
                                        grid.rows.sort((m, n) => {
                                            if (m.cells.length > j && n.cells.length > j) {
                                                if (m.cells[j].value > n.cells[j].value) {
                                                    return -1;
                                                }
                                                else if (m.cells[j].value < n.cells[j].value) {
                                                    return 1;
                                                }
                                                else
                                                    return 0;
                                            }
                                            else {
                                                return 0;
                                            }
                                        });
                                    }
                                }
                                else {
                                    tColumn.sort = "none";
                                }
                            }
                            else {
                                tColumn.sort = "none";
                            }
                        }
                        if (grid.onClickGridColumn) {
                            grid.onClickGridColumn(grid, gridColumn, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
                        }
                        else if (grid.paint && grid.paint.onClickGridColumn) {
                            grid.paint.onClickGridColumn(grid, gridColumn, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
                        }
                        return;
                    }
                }
                cLeft += gridColumn.width;
            }
        }
    }
    for (let i = 0; i < grid.rows.length; i++) {
        let row = grid.rows[i];
        if (row.visible) {
            let rTop = cTop, rBottom = cTop + grid.rowHeight;
            if (rBottom >= 0 && cTop <= grid.size.cy) {
                for (let j = 0; j < row.cells.length; j++) {
                    let cell = row.cells[j];
                    let gridColumn = cell.column;
                    if (!gridColumn) {
                        gridColumn = grid.columns[j];
                    }
                    if (gridColumn.visible) {
                        if (gridColumn.frozen) {
                            let cellWidth = gridColumn.width;
                            let colSpan = cell.colSpan;
                            if (colSpan > 1) {
                                for (let n = 1; n < colSpan; n++) {
                                    let spanColumn = grid.columns[gridColumn.index + n];
                                    if (spanColumn && spanColumn.visible) {
                                        cellWidth += spanColumn.width;
                                    }
                                }
                            }
                            let cellHeight = grid.rowHeight;
                            let rowSpan = cell.rowSpan;
                            if (rowSpan > 1) {
                                for (let n = 1; n < rowSpan; n++) {
                                    let spanRow = grid.rows[i + n];
                                    if (spanRow && spanRow.visible) {
                                        cellHeight += grid.rowHeight;
                                    }
                                }
                            }
                            let cRect = new FCRect(gridColumn.bounds.left, rTop, gridColumn.bounds.left + cellWidth, rTop + cellHeight);
                            if (cRect.right >= 0 && cRect.left < grid.size.cx) {
                                if (firstPoint.x >= cRect.left && firstPoint.x <= cRect.right && firstPoint.y >= cRect.top && firstPoint.y <= cRect.bottom) {
                                    for (let r = 0; r < grid.rows.length; r++) {
                                        let subRow = grid.rows[r];
                                        if (subRow == row) {
                                            subRow.selected = true;
                                        }
                                        else {
                                            subRow.selected = false;
                                        }
                                    }
                                    if (grid.onClickGridCell) {
                                        grid.onClickGridCell(grid, row, gridColumn, cell, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
                                    }
                                    else if (grid.paint && grid.paint.onClickGridCell) {
                                        grid.paint.onClickGridCell(grid, row, gridColumn, cell, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
                                    }
                                    return;
                                }
                            }
                        }
                    }
                }
            }
            if (rBottom >= 0 && cTop <= grid.size.cy) {
                for (let j = 0; j < row.cells.length; j++) {
                    let cell = row.cells[j];
                    let gridColumn = cell.column;
                    if (!gridColumn) {
                        gridColumn = grid.columns[j];
                    }
                    if (gridColumn.visible) {
                        if (!gridColumn.frozen) {
                            let cellWidth = gridColumn.width;
                            let colSpan = cell.colSpan;
                            if (colSpan > 1) {
                                for (let n = 1; n < colSpan; n++) {
                                    let spanColumn = grid.columns[gridColumn.index + n];
                                    if (spanColumn && spanColumn.visible) {
                                        cellWidth += spanColumn.width;
                                    }
                                }
                            }
                            let cellHeight = grid.rowHeight;
                            let rowSpan = cell.rowSpan;
                            if (rowSpan > 1) {
                                for (let n = 1; n < rowSpan; n++) {
                                    let spanRow = grid.rows[i + n];
                                    if (spanRow && spanRow.visible) {
                                        cellHeight += grid.rowHeight;
                                    }
                                }
                            }
                            let cRect = new FCRect(gridColumn.bounds.left - grid.scrollH, rTop, gridColumn.bounds.left + cellWidth - grid.scrollH, rTop + cellHeight);
                            if (cRect.right >= 0 && cRect.left < grid.size.cx) {
                                if (firstPoint.x >= cRect.left && firstPoint.x <= cRect.right && firstPoint.y >= cRect.top && firstPoint.y <= cRect.bottom) {
                                    for (let r = 0; r < grid.rows.length; r++) {
                                        let subRow = grid.rows[r];
                                        if (subRow == row) {
                                            subRow.selected = true;
                                        }
                                        else {
                                            subRow.selected = false;
                                        }
                                    }
                                    if (grid.onClickGridCell) {
                                        grid.onClickGridCell(grid, row, gridColumn, cell, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
                                    }
                                    else if (grid.paint && grid.paint.onClickGridCell) {
                                        grid.paint.onClickGridCell(grid, row, gridColumn, cell, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
                                    }
                                    return;
                                }
                            }
                        }
                    }
                }
            }
            if (cTop > grid.size.cy) {
                break;
            }
            cTop += grid.rowHeight;
        }
    }
}
/*
* 检查拖动滚动
*/
function checkGridDragScroll() {
    if (g_dragScrollView_Grid) {
        let sub = Math.floor(g_scrollAddSpeed_Grid / 10);
        if (sub == 0 && g_scrollAddSpeed_Grid > 1) {
            sub = 1;
        }
        else if (sub == 0 && g_scrollAddSpeed_Grid < -1) {
            sub = -1;
        }
        g_scrollAddSpeed_Grid -= sub;
        if (Math.abs(sub) <= 1) {
            let viewCache = g_dragScrollView_Grid;
            g_dragScrollView_Grid = null;
            g_scrollAddSpeed_Grid = 0;
            if (viewCache.paint) {
                invalidateView(viewCache);
            }
        }
        else {
            let oldScrollV = Math.floor(g_dragScrollView_Grid.scrollV + g_scrollAddSpeed_Grid);
            let oldScrollH = Math.floor(g_dragScrollView_Grid.scrollH + g_scrollAddSpeed_Grid);
            if (g_scrollDirection_Grid == 0) {
                let contentHeight = getGridContentHeight(g_dragScrollView_Grid);
                if (contentHeight < g_dragScrollView_Grid.size.cy - g_dragScrollView_Grid.scrollSize) {
                    g_dragScrollView_Grid.scrollV = 0;
                }
                else {
                    if (oldScrollV < 0) {
                        oldScrollV = 0;
                    }
                    else if (oldScrollV > contentHeight - g_dragScrollView_Grid.size.cy + g_dragScrollView_Grid.headerHeight + g_dragScrollView_Grid.scrollSize) {
                        oldScrollV = contentHeight - g_dragScrollView_Grid.size.cy + g_dragScrollView_Grid.headerHeight + g_dragScrollView_Grid.scrollSize;
                    }
                    g_dragScrollView_Grid.scrollV = oldScrollV;
                }
            }
            else {
                let contentWidth = getGridContentWidth(g_dragScrollView_Grid);
                if (contentWidth < g_dragScrollView_Grid.size.cx - g_dragScrollView_Grid.headerHeight - g_dragScrollView_Grid.scrollSize) {
                    g_dragScrollView_Grid.scrollH = 0;
                }
                else {
                    if (oldScrollH < 0) {
                        oldScrollH = 0;
                    }
                    else if (oldScrollH > contentWidth - g_dragScrollView_Grid.size.cx) {
                        oldScrollH = contentWidth - g_dragScrollView_Grid.size.cx;
                    }
                    g_dragScrollView_Grid.scrollH = oldScrollH;
                }
            }
            if (g_dragScrollView_Grid.paint) {
                invalidateView(g_dragScrollView_Grid);
            }
        }
    }
}
/*
* 表格的鼠标滚轮方法
* grid:表格
* delta:滚轮值
*/
function touchWheelGrid(grid, delta) {
    let oldScrollV = grid.scrollV;
    if (delta < 0) {
        oldScrollV -= 20;
    }
    else if (delta > 0) {
        oldScrollV += 20;
    }
    let contentHeight = getGridContentHeight(grid);
    if (contentHeight < grid.size.cy - grid.headerHeight - grid.scrollSize) {
        grid.scrollV = 0;
    }
    else {
        if (oldScrollV < 0) {
            oldScrollV = 0;
        }
        else if (oldScrollV > contentHeight - grid.size.cy + grid.headerHeight + grid.scrollSize) {
            oldScrollV = contentHeight - grid.size.cy + grid.headerHeight + grid.scrollSize;
        }
        grid.scrollV = oldScrollV;
    }
}
/*
* 创建文本框实体
* textBox:文本框
*/
function createInputTextBox(textBox) {
    let input = document.createElement("input");
    textBox.input = input;
    input.type = "text";
    input.style.position = "absolute";
    input.style.boxSizing = "border-box";
    if (textBox.font && textBox.paint) {
        let strs = textBox.font.split(',');
        let fontFamily = strs[0];
        if (fontFamily == "Default") {
            fontFamily = textBox.paint.systemFont;
        }
        let sFont = strs[1] + "px " + fontFamily;
        if (textBox.paint.scaleFactorX != 1 || textBox.paint.scaleFactorY != 1) {
            sFont = Math.min(textBox.paint.scaleFactorX, textBox.paint.scaleFactorY) * parseFloat(strs[1]) + "px " + fontFamily;
        }
        input.style.font = sFont;
    }
    document.body.appendChild(input);
    input.value = textBox.text;
}
/*
* 重置布局图层
* layout:布局层
*/
function resetLayoutDiv(layout) {
    let reset = false;
    let padding = new FCPadding(0, 0, 0, 0);
    if (layout.padding) {
        padding = layout.padding;
    }
    let vPos = 0, left = padding.left, top = padding.top, width = layout.size.cx - padding.left - padding.right, height = layout.size.cy - padding.top - padding.bottom;
    for (let i = 0; i < layout.views.length; i++) {
        let view = layout.views[i];
        if (view.visible) {
            let size = view.size;
            let margin = new FCPadding(0, 0, 0, 0);
            if (view.margin) {
                margin = view.margin;
            }
            let cLeft = view.location.x, cTop = view.location.y, cWidth = size.cx, cHeight = size.cy;
            let nLeft = cLeft, nTop = cTop, nWidth = cWidth, nHeight = cHeight;
            if (layout.layoutStyle == "bottomtotop") {
                if (i == 0) {
                    top = height - padding.top;
                }
                let lWidth = 0;
                if (layout.autoWrap) {
                    lWidth = size.cx;
                    let lTop = top - margin.top - cHeight - margin.bottom;
                    if (lTop < padding.top) {
                        if (vPos != 0) {
                            left += cWidth + margin.left;
                        }
                        top = height - padding.top;
                    }
                }
                else {
                    lWidth = width - margin.left - margin.right;
                }
                top -= cHeight + margin.bottom;
                nLeft = left + margin.left;
                nWidth = lWidth;
                nTop = top;
            }
            else if (layout.layoutStyle == "lefttoright") {
                let lHeight = 0;
                if (layout.autoWrap) {
                    lHeight = size.cy;
                    let lRight = left + margin.left + cWidth + margin.right;
                    if (lRight > width) {
                        left = padding.left;
                        if (vPos != 0) {
                            top += cHeight + margin.top;
                        }
                    }
                }
                else {
                    lHeight = height - margin.top - margin.bottom;
                }
                left += margin.left;
                nLeft = left;
                nTop = top + margin.top;
                nHeight = lHeight;
                left += cWidth + margin.right;
            }
            else if (layout.layoutStyle == "righttoleft") {
                if (i == 0) {
                    left = width - padding.left;
                }
                let lHeight = 0;
                if (layout.autoWrap) {
                    lHeight = size.cy;
                    let lLeft = left - margin.left - cWidth - margin.right;
                    if (lLeft < padding.left) {
                        left = width - padding.left;
                        if (vPos != 0) {
                            top += cHeight + margin.top;
                        }
                    }
                }
                else {
                    lHeight = height - margin.top - margin.bottom;
                }
                left -= cWidth + margin.left;
                nLeft = left;
                nTop = top + margin.top;
                nHeight = lHeight;
            }
            else if (layout.layoutStyle == "toptobottom") {
                let lWidth = 0;
                if (layout.autoWrap) {
                    lWidth = size.cx;
                    let lBottom = top + margin.top + cHeight + margin.bottom;
                    if (lBottom > height) {
                        if (vPos != 0) {
                            left += cWidth + margin.left + margin.right;
                        }
                        top = padding.top;
                    }
                }
                else {
                    lWidth = width - margin.left - margin.right;
                }
                top += margin.top;
                nTop = top;
                nLeft = left + margin.left;
                nWidth = lWidth;
                top += cHeight + margin.bottom;
            }
            if (cLeft != nLeft || cTop != nTop || cWidth != nWidth || cHeight != nHeight) {
                view.location = new FCPoint(nLeft, nTop);
                view.size = new FCSize(nWidth, nHeight);
                reset = true;
            }
            vPos++;
        }
    }
    return reset;
}
/*
* 更新页的布局
* tabView:多页夹
* tabPage:页
* left:左侧坐标
* top:上方坐标
* width:宽度
* height:高度
* tw:页头按钮的宽度
* th:页头按钮的高度
*/
function updataPageLayout(tabView, tabPage, left, top, width, height, tw, th) {
    let newBounds = new FCRect(0, 0, 0, 0);
    if (tabView.layout == "bottom") {
        newBounds.left = 0;
        newBounds.top = 0;
        newBounds.right = width;
        newBounds.bottom = height - th;
        tabPage.headerButton.location = new FCPoint(left, height - th);
    }
    else if (tabView.layout == "left") {
        newBounds.left = tw;
        newBounds.top = 0;
        newBounds.right = width;
        newBounds.bottom = height;
        tabPage.headerButton.location = new FCPoint(0, top);
    }
    else if (tabView.layout == "right") {
        newBounds.left = 0;
        newBounds.top = 0;
        newBounds.right = width - tw;
        newBounds.bottom = height;
        tabPage.headerButton.location = new FCPoint(width - tw, top);
    }
    else if (tabView.layout == "top") {
        newBounds.left = 0;
        newBounds.top = th;
        newBounds.right = width;
        newBounds.bottom = height;
        tabPage.headerButton.location = new FCPoint(left, 0);
    }
    tabPage.location = new FCPoint(newBounds.left, newBounds.top);
    tabPage.size = new FCSize(newBounds.right - newBounds.left, newBounds.bottom - newBounds.top);
}
/*
* 更新多页夹的布局
* tabView:多页夹
*/
function updateTabLayout(tabView) {
    let width = tabView.size.cx;
    let height = tabView.size.cy;
    let left = 0, top = 0;
    for (let i = 0; i < tabView.tabPages.length; i++) {
        let tabPage = tabView.tabPages[i];
        let headerButton = tabView.tabPages[i].headerButton;
        if (headerButton.visible) {
            let tw = headerButton.size.cx;
            let th = headerButton.size.cy;
            updataPageLayout(tabView, tabPage, left, top, width, height, tw, th);
            left += tw;
            top += th;
        }
        else {
            tabPage.visible = false;
        }
    }
}
/*
* 重置分割线的布局
* split:分割视图
*/
function resetSplitLayoutDiv(split) {
    let reset = false;
    let splitRect = new FCRect(0, 0, 0, 0);
    let width = split.size.cx, height = split.size.cy;
    let fRect = new FCRect(0, 0, 0, 0);
    let sRect = new FCRect(0, 0, 0, 0);
    let splitterSize = new FCSize(0, 0);
    if (split.splitter.visible) {
        splitterSize.cx = split.splitter.size.cx;
        splitterSize.cy = split.splitter.size.cy;
    }
    split.splitter.topMost = true;
    let layoutStyle = split.layoutStyle;
    if (layoutStyle == "bottomtotop") {
        if (split.splitMode == "absolutesize" || split.oldSize.cy == 0) {
            splitRect.left = 0;
            splitRect.top = height - (split.oldSize.cy - split.splitter.location.y);
            splitRect.right = width;
            splitRect.bottom = splitRect.top + splitterSize.cy;
        }
        else if (split.splitMode == "percentsize") {
            splitRect.left = 0;
            if (split.splitPercent == -1) {
                split.splitPercent = split.splitter.location.y / split.oldSize.cy;
            }
            splitRect.top = height * split.splitPercent;
            splitRect.right = width;
            splitRect.bottom = splitRect.top + splitterSize.cy;
        }
        fRect.left = 0;
        fRect.top = splitRect.bottom;
        fRect.right = width;
        fRect.bottom = height;
        sRect.left = 0;
        sRect.top = 0;
        sRect.right = width;
        sRect.bottom = splitRect.top;
    }
    else if (layoutStyle == "lefttoright") {
        if (split.splitMode == "absolutesize" || split.oldSize.cx == 0) {
            splitRect.left = split.splitter.location.x;
            splitRect.top = 0;
            splitRect.right = splitRect.left + splitterSize.cx;
            splitRect.bottom = height;
        }
        else if (split.splitMode == "percentsize") {
            if (split.splitPercent == -1) {
                split.splitPercent = split.splitter.location.x / split.oldSize.cx;
            }
            splitRect.left = width * split.splitPercent;
            splitRect.top = 0;
            splitRect.right = splitRect.left + splitterSize.cx;
            splitRect.bottom = height;
        }
        fRect.left = 0;
        fRect.top = 0;
        fRect.right = splitRect.left;
        fRect.bottom = height;
        sRect.left = splitRect.right;
        sRect.top = 0;
        sRect.right = width;
        sRect.bottom = height;
    }
    else if (layoutStyle == "righttoleft") {
        if (split.splitMode == "absolutesize" || split.oldSize.cx == 0) {
            splitRect.left = width - (split.oldSize.cx - split.splitter.location.x);
            splitRect.top = 0;
            splitRect.right = splitRect.left + splitterSize.cx;
            splitRect.bottom = height;
        }
        else if (split.splitMode == "percentsize") {
            if (split.splitPercent == -1) {
                split.splitPercent = split.splitter.location.x / split.oldSize.cx;
            }
            splitRect.left = width * split.splitPercent;
            splitRect.top = 0;
            splitRect.right = splitRect.left + splitterSize.cx;
            splitRect.bottom = height;
        }
        fRect.left = splitRect.right;
        fRect.top = 0;
        fRect.right = width;
        fRect.bottom = height;
        sRect.left = 0;
        sRect.top = 0;
        sRect.right = splitRect.left;
        sRect.bottom = height;
    }
    else if (layoutStyle == "toptobottom") {
        if (split.splitMode == "absolutesize" || split.oldSize.cy == 0) {
            splitRect.left = 0;
            splitRect.top = split.splitter.location.y;
            splitRect.right = width;
            splitRect.bottom = splitRect.top + splitterSize.cy;
        }
        else if (split.splitMode == "percentsize") {
            splitRect.left = 0;
            if (split.splitPercent == -1) {
                split.splitPercent = split.splitter.location.y / split.oldSize.cy;
            }
            splitRect.top = height * split.splitPercent;
            splitRect.right = width;
            splitRect.bottom = splitRect.top + splitterSize.cy;
        }
        fRect.left = 0;
        fRect.top = 0;
        fRect.right = width;
        fRect.bottom = splitRect.top;
        sRect.left = 0;
        sRect.top = splitRect.bottom;
        sRect.right = width;
        sRect.bottom = height;
    }
    if (split.splitter.visible) {
        let spRect = new FCRect(split.splitter.location.x, split.splitter.location.y, split.splitter.location.x + split.splitter.size.cx, split.splitter.location.y + split.splitter.size.cy);
        if (spRect.left != splitRect.left || spRect.top != splitRect.top || spRect.right != splitRect.right || spRect.bottom != splitRect.bottom) {
            split.splitter.location = new FCPoint(splitRect.left, splitRect.top);
            split.splitter.size = new FCSize(splitRect.right - splitRect.left, splitRect.bottom - splitRect.top);
            reset = true;
        }
    }
    let fcRect = new FCRect(split.firstView.location.x, split.firstView.location.y, split.firstView.location.x + split.firstView.size.cx, split.firstView.location.y + split.firstView.size.cy);
    if (fcRect.left != fRect.left || fcRect.top != fRect.top || fcRect.right != fRect.right || fcRect.bottom != fRect.bottom) {
        reset = true;
        split.firstView.location = new FCPoint(fRect.left, fRect.top);
        split.firstView.size = new FCSize(fRect.right - fRect.left, fRect.bottom - fRect.top);
    }
    let scRect = new FCRect(split.secondView.location.x, split.secondView.location.y, split.secondView.location.x + split.secondView.size.cx, split.secondView.location.y + split.secondView.size.cy);
    if (scRect.left != sRect.left || scRect.top != sRect.top || scRect.right != sRect.right || scRect.bottom != sRect.bottom) {
        reset = true;
        split.secondView.location = new FCPoint(sRect.left, sRect.top);
        split.secondView.size = new FCSize(sRect.right - sRect.left, sRect.bottom - sRect.top);
    }
    split.oldSize = new FCSize(width, height);
    return reset;
}
/*
* 添加页
* tabView:多页夹
* tabPage:页
* tabButton:页头按钮
*/
function addTabPage(tabView, tabPage, tabButton) {
    tabPage.headerButton = tabButton;
    tabPage.parent = tabView;
    tabPage.paint = tabView.paint;
    tabButton.parent = tabView;
    tabButton.paint = tabView.paint;
    tabView.tabPages.push(tabPage);
    tabView.views.push(tabPage);
    tabView.views.push(tabButton);
}
/*
* 移除页
* tabView:多页夹
* tabPage:页
*/
function removeTabPage(tabView, pageOrButton) {
    for (let i = 0; i < tabView.tabPages.length; i++) {
        let tabPage = tabView.tabPages[i];
        if (tabPage.headerButton == pageOrButton || tabPage == pageOrButton) {
            tabView.tabPages.splice(i, 1);
            removeViewFromParent(tabPage.headerButton, tabView);
            removeViewFromParent(tabPage, tabView);
            break;
        }
    }
    if (tabView.tabPages.length > 0) {
        selectTabPage(tabView, tabView.tabPages[0]);
    }
    updateTabLayout(tabView);
}
/*
* 选中页
* tabView:多页夹
* tabPage:页
*/
function selectTabPage(tabView, tabPage) {
    for (let i = 0; i < tabView.tabPages.length; i++) {
        let tp = tabView.tabPages[i];
        if (tp == tabPage) {
            tp.visible = true;
        }
        else {
            tp.visible = false;
        }
    }
    updateTabLayout(tabView);
}
//动画中的页夹
let animationTabPages = [];
/*
* 检查页的动画
*/
function checkTabPageAnimation() {
    if (animationTabPages.length > 0) {
        for (let i = 0; i < animationTabPages.length; i++) {
            let tp = animationTabPages[i];
            if (tp.parent) {
                let tabView = tp.parent;
                if (tabView.underPoint) {
                    let location = tp.headerButton.location;
                    if (location.x > tabView.underPoint.x) {
                        tabView.underPoint.x += tabView.animationSpeed;
                    }
                    else if (location.x < tabView.underPoint.x) {
                        tabView.underPoint.x -= tabView.animationSpeed;
                    }
                    if (location.y > tabView.underPoint.y) {
                        tabView.underPoint.y += tabView.animationSpeed;
                    }
                    else if (location.y < tabView.underPoint.y) {
                        tabView.underPoint.y -= tabView.animationSpeed;
                    }
                    if (Math.abs(location.x - tabView.underPoint.x) <= tabView.animationSpeed && Math.abs(location.y - tabView.underPoint.y) <= tabView.animationSpeed) {
                        tabView.underPoint = null;
                        animationTabPages.splice(i, 1);
                    }
                }
                if (tp.parent.paint) {
                    invalidateView(tp.parent);
                }
            }
            else {
                animationTabPages.splice(i, 1);
            }
            break;
        }
    }
}
/*
* 重绘多页加
* tabView:多页夹
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawTabViewBorder(tabView, paint, clipRect) {
    if (tabView.underLineColor && tabView.underLineColor != "none") {
        for (let i = 0; i < tabView.tabPages.length; i++) {
            let tp = tabView.tabPages[i];
            if (tp.visible) {
                let headerButton = tp.headerButton;
                let location = new FCPoint(headerButton.location.x, headerButton.location.y);
                let size = headerButton.size;
                if (tabView.useAnimation) {
                    if (tabView.underPoint) {
                        location.x = tabView.underPoint.x;
                        location.y = tabView.underPoint.y;
                    }
                }
                if (tabView.layout == "bottom") {
                    paint.fillRect(tabView.underLineColor, location.x, location.y, location.x + size.cx, location.y + tabView.underLineSize);
                }
                else if (tabView.layout == "left") {
                    paint.fillRect(tabView.underLineColor, location.x + size.cx - tabView.underLineSize, location.y, location.x + size.cx, location.y + size.cy);
                }
                else if (tabView.layout == "top") {
                    paint.fillRect(tabView.underLineColor, location.x, location.y + size.cy - tabView.underLineSize, location.x + size.cx, location.y + size.cy);
                }
                else if (tabView.layout == "right") {
                    paint.fillRect(tabView.underLineColor, location.x, location.y, location.x + tabView.underLineSize, location.y + size.cy);
                }
                break;
            }
        }
    }
}
/*
* 获取总的偏移量
* node:树节点
*/
function getTotalIndent(node) {
    if (node.parentNode) {
        return node.indent + getTotalIndent(node.parentNode);
    }
    else {
        return node.indent;
    }
}
/*
* 绘制单元格
* tree:树
* row:行
* column:列
* node:节点
* paint:绘图对象
* left:左侧坐标
* top:上方坐标
* right:右侧坐标
* bottom:下方坐标
*/
function drawTreeNode(tree, row, column, node, paint, left, top, right, bottom) {
    if (node.backColor && node.backColor != "none") {
        paint.fillRect(node.backColor, left, top, right, bottom);
    }
    if (row.selected) {
        if (tree.selectedRowColor && tree.selectedRowColor != "none") {
            paint.fillRect(tree.selectedRowColor, left, top, right, bottom);
        }
    }
    if (node.value) {
        let tSize = paint.textSize(node.value, node.font);
        let tLeft = left + 2 + getTotalIndent(node);
        let wLeft = tLeft;
        let cR = tree.checkBoxWidth / 3;
        if (tree.showCheckBox) {
            wLeft += tree.checkBoxWidth;
            if (node.checked) {
                paint.fillRect(node.textColor, tLeft + (tree.checkBoxWidth - cR) / 2, top + (tree.rowHeight - cR) / 2, tLeft + (tree.checkBoxWidth + cR) / 2, top + (tree.rowHeight + cR) / 2);
            }
            else {
                paint.drawRect(node.textColor, 1, null, tLeft + (tree.checkBoxWidth - cR) / 2, top + (tree.rowHeight - cR) / 2, tLeft + (tree.checkBoxWidth + cR) / 2, top + (tree.rowHeight + cR) / 2);
            }
        }
        if (node.childNodes.length > 0) {
            paint.beginPath();
            if (node.collapsed) {
                paint.addLine(wLeft + (tree.collapsedWidth + cR) / 2, top + tree.rowHeight / 2, wLeft + (tree.collapsedWidth - cR) / 2, top + (tree.rowHeight - cR) / 2);
                paint.addLine(wLeft + (tree.collapsedWidth - cR) / 2, top + (tree.rowHeight - cR) / 2, wLeft + (tree.collapsedWidth - cR) / 2, top + (tree.rowHeight + cR) / 2);
                paint.addLine(wLeft + (tree.collapsedWidth - cR) / 2, top + (tree.rowHeight + cR) / 2, wLeft + (tree.collapsedWidth + cR) / 2, top + tree.rowHeight / 2);
            }
            else {
                paint.addLine(wLeft + (tree.collapsedWidth - cR) / 2, top + (tree.rowHeight - cR) / 2, wLeft + (tree.collapsedWidth + cR) / 2, top + (tree.rowHeight - cR) / 2);
                paint.addLine(wLeft + (tree.collapsedWidth + cR) / 2, top + (tree.rowHeight - cR) / 2, wLeft + tree.collapsedWidth / 2, top + (tree.rowHeight + cR) / 2);
                paint.addLine(wLeft + tree.collapsedWidth / 2, top + (tree.rowHeight + cR) / 2, wLeft + (tree.collapsedWidth - cR) / 2, top + (tree.rowHeight - cR) / 2);
            }
            paint.fillPath(node.textColor);
            paint.closePath();
            wLeft += tree.collapsedWidth;
        }
        if (tSize.cx > column.width) {
            paint.drawTextAutoEllipsis(node.value, node.textColor, node.font, wLeft, top + tree.rowHeight / 2 - tSize.cy / 2, wLeft + column.width, top + tree.rowHeight / 2 - tSize.cy / 2);
        }
        else {
            paint.drawText(node.value, node.textColor, node.font, wLeft, top + tree.rowHeight / 2 - tSize.cy / 2);
        }
    }
}
/*
* 绘制树
* tree:树
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawTree(tree, paint, clipRect) {
    let cLeft = -tree.scrollH;
    let cTop = -tree.scrollV + tree.headerHeight;
    //绘制行
    let colLeft = 0;
    for (let i = 0; i < tree.columns.length; i++) {
        if (tree.columns[i].widthStr.length > 0) {
            let newWidthStr = tree.columns[i].widthStr.replace("%", "");
            tree.columns[i].width = Number(newWidthStr) * tree.size.cx / 100;
        }
        let colRect = new FCRect(colLeft, 0, colLeft + tree.columns[i].width, tree.headerHeight);
        tree.columns[i].bounds = colRect;
        tree.columns[i].index = i;
        colLeft += tree.columns[i].width;
    }
    updateTreeRowIndex(tree);
    for (let i = 0; i < tree.rows.length; i++) {
        let row = tree.rows[i];
        if (row.visible) {
            let rTop = cTop, rBottom = cTop + tree.rowHeight;
            if (rBottom >= 0 && cTop <= tree.size.cy) {
                for (let j = 0; j < row.cells.length; j++) {
                    let node = row.cells[j];
                    let treeColumn = node.column;
                    if (!treeColumn) {
                        treeColumn = tree.columns[j];
                    }
                    if (treeColumn.visible) {
                        let nodeWidth = treeColumn.width;
                        let nodeHeight = tree.rowHeight;
                        let cRect = new FCRect(treeColumn.bounds.left - tree.scrollH, rTop, treeColumn.bounds.left + nodeWidth - tree.scrollH, rTop + nodeHeight);
                        if (cRect.right >= 0 && cRect.left < tree.size.cx) {
                            if (tree.onPaintTreeNode) {
                                tree.onPaintTreeNode(tree, row, treeColumn, node, paint, cRect.left, cRect.top, cRect.right, cRect.bottom);
                            }
                            else if (paint.onPaintTreeNode) {
                                paint.onPaintTreeNode(tree, row, treeColumn, node, paint, cRect.left, cRect.top, cRect.right, cRect.bottom);
                            }
                            else {
                                drawTreeNode(tree, row, treeColumn, node, paint, cRect.left, cRect.top, cRect.right, cRect.bottom);
                            }
                        }
                    }
                }
            }
            if (cTop > tree.size.cy) {
                break;
            }
            cTop += tree.rowHeight;
        }
    }
}
/*
* 绘制滚动条
* tree:树
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawTreeScrollBar(tree, paint, clipRect) {
    tree.hScrollIsVisible = false;
    tree.vScrollIsVisible = false;
    if (paint.isMobile) {
        if (paint.touchDownView == tree) {
        }
        else if (g_dragScrollView_Tree == tree && g_scrollAddSpeed_Tree != 0) {
        }
        else {
            return;
        }
    }
    if (tree.showHScrollBar) {
        let contentWidth = getTreeContentWidth(tree);
        if (contentWidth > 0 && contentWidth > tree.size.cx) {
            let sLeft = tree.scrollH / contentWidth * tree.size.cx;
            let sRight = (tree.scrollH + tree.size.cx) / contentWidth * tree.size.cx;
            if (sRight - sLeft < tree.scrollSize) {
                sRight = sLeft + tree.scrollSize;
            }
            if (paint.touchMoveView == tree && (tree.hoverScrollHButton || tree.downScrollHButton)) {
                paint.fillRect(tree.scrollBarHoveredColor, sLeft, tree.size.cy - tree.scrollSize, sRight, tree.size.cy);
            }
            else {
                paint.fillRect(tree.scrollBarColor, sLeft, tree.size.cy - tree.scrollSize, sRight, tree.size.cy);
            }
            tree.hScrollIsVisible = true;
        }
    }
    if (tree.showVScrollBar) {
        let contentHeight = getTreeContentHeight(tree);
        if (contentHeight > 0 && contentHeight > tree.size.cy) {
            let sTop = tree.headerHeight + tree.scrollV / contentHeight * (tree.size.cy - tree.headerHeight - tree.scrollSize);
            let sBottom = sTop + ((tree.size.cy - tree.headerHeight)) / contentHeight * (tree.size.cy - tree.headerHeight - tree.scrollSize);
            if (sBottom - sTop < tree.scrollSize) {
                sBottom = sTop + tree.scrollSize;
            }
            if (paint.touchMoveView == tree && (tree.hoverScrollVButton || tree.downScrollVButton)) {
                paint.fillRect(tree.scrollBarHoveredColor, tree.size.cx - tree.scrollSize, sTop, tree.size.cx, sBottom);
            }
            else {
                paint.fillRect(tree.scrollBarColor, tree.size.cx - tree.scrollSize, sTop, tree.size.cx, sBottom);
            }
            tree.vScrollIsVisible = true;
        }
    }
}
/*
* 获取内容的宽度
* tree:树
*/
function getTreeContentWidth(tree) {
    let cWidth = 0;
    for (let i = 0; i < tree.columns.length; i++) {
        if (tree.columns[i].visible) {
            cWidth += tree.columns[i].width;
        }
    }
    return cWidth;
}
/*
* 获取内容的高度
* tree:树
*/
function getTreeContentHeight(tree) {
    let cHeight = 0;
    for (let i = 0; i < tree.rows.length; i++) {
        if (tree.rows[i].visible) {
            cHeight += tree.rowHeight;
        }
    }
    return cHeight;
}
/*
* 树的鼠标移动方法
* tree: 树
* firstTouch:是否第一次触摸
* firstPoint:第一次触摸的坐标
* secondTouch:是否第二次触摸
* secondPoint:第二次触摸的坐标
*/
function touchMoveTree(tree, firstTouch, firstPoint, secondTouch, secondPoint) {
    tree.hoverScrollHButton = false;
    tree.hoverScrollVButton = false;
    let mp = firstPoint;
    if (firstTouch) {
        if (tree.showHScrollBar || tree.showVScrollBar) {
            if (tree.downScrollHButton) {
                let contentWidth = getTreeContentWidth(tree);
                let subX = (mp.x - tree.startPoint.x) / tree.size.cx * contentWidth;
                let newScrollH = tree.startScrollH + subX;
                if (newScrollH < 0) {
                    newScrollH = 0;
                }
                else if (newScrollH > contentWidth - tree.size.cx) {
                    newScrollH = contentWidth - tree.size.cx;
                }
                tree.scrollH = newScrollH;
                tree.paint.cancelClick = true;
                return;
            }
            else if (tree.downScrollVButton) {
                let contentHeight = getTreeContentHeight(tree);
                let subY = (mp.y - tree.startPoint.y) / (tree.size.cy - tree.headerHeight - tree.scrollSize) * contentHeight;
                let newScrollV = tree.startScrollV + subY;
                if (newScrollV < 0) {
                    newScrollV = 0;
                }
                else if (newScrollV > contentHeight - (tree.size.cy - tree.headerHeight - tree.scrollSize)) {
                    newScrollV = contentHeight - (tree.size.cy - tree.headerHeight - tree.scrollSize);
                }
                tree.scrollV = newScrollV;
                tree.paint.cancelClick = true;
                return;
            }
        }
        if (tree.allowDragScroll) {
            let contentWidth = getTreeContentWidth(tree);
            if (contentWidth > tree.size.cx) {
                let subX = tree.startPoint.x - mp.x;
                let newScrollH = tree.startScrollH + subX;
                if (newScrollH < 0) {
                    newScrollH = 0;
                }
                else if (newScrollH > contentWidth - tree.size.cx) {
                    newScrollH = contentWidth - tree.size.cx;
                }
                tree.scrollH = newScrollH;
                if (Math.abs(subX) > 5) {
                    tree.paint.cancelClick = true;
                }
            }
            let contentHeight = getTreeContentHeight(tree);
            if (contentHeight > tree.size.cy) {
                let subY = tree.startPoint.y - mp.y;
                let newScrollV = tree.startScrollV + subY;
                if (newScrollV < 0) {
                    newScrollV = 0;
                }
                else if (newScrollV > contentHeight - (tree.size.cy - tree.headerHeight - tree.scrollSize)) {
                    newScrollV = contentHeight - (tree.size.cy - tree.headerHeight - tree.scrollSize);
                }
                tree.scrollV = newScrollV;
                if (Math.abs(subY) > 5) {
                    tree.paint.cancelClick = true;
                }
            }
        }
    }
    else {
        if (tree.showHScrollBar) {
            let contentWidth = getTreeContentWidth(tree);
            if (contentWidth > 0 && contentWidth > tree.size.cx) {
                let sLeft = tree.scrollH / contentWidth * tree.size.cx;
                let sRight = (tree.scrollH + tree.size.cx) / contentWidth * tree.size.cx;
                if (sRight - sLeft < tree.scrollSize) {
                    sRight = sLeft + tree.scrollSize;
                }
                if (mp.x >= sLeft && mp.x <= sRight && mp.y >= tree.size.cy - tree.scrollSize && mp.y <= tree.size.cy) {
                    tree.hoverScrollHButton = true;
                    return;
                }
                else {
                    tree.hoverScrollHButton = false;
                }
            }
        }
        if (tree.showVScrollBar) {
            let contentHeight = getTreeContentHeight(tree);
            if (contentHeight > 0 && contentHeight > tree.size.cy) {
                let sTop = tree.headerHeight + tree.scrollV / contentHeight * (tree.size.cy - tree.headerHeight - tree.scrollSize);
                let sBottom = tree.headerHeight + (tree.scrollV + (tree.size.cy - tree.headerHeight - tree.scrollSize)) / contentHeight * (tree.size.cy - tree.headerHeight - tree.scrollSize);
                if (sBottom - sTop < tree.scrollSize) {
                    sBottom = sTop + tree.scrollSize;
                }
                if (mp.x >= tree.size.cx - tree.scrollSize && mp.x <= tree.size.cx && mp.y >= sTop && mp.y <= sBottom) {
                    tree.hoverScrollVButton = true;
                    return;
                }
                else {
                    tree.hoverScrollVButton = false;
                }
            }
        }
    }
}
/*
* 树的鼠标按下方法
* tree: 树
* firstTouch:是否第一次触摸
* firstPoint:第一次触摸的坐标
* secondTouch:是否第二次触摸
* secondPoint:第二次触摸的坐标
* clicks:点击次数
*/
function touchDownTree(tree, firstTouch, firstPoint, secondTouch, secondPoint, clicks) {
    let mp = firstPoint;
    tree.touchDownTime = new Date().getTime();
    tree.startPoint = mp;
    tree.downScrollHButton = false;
    tree.downScrollVButton = false;
    g_dragScrollView_Tree = null;
    g_scrollAddSpeed_Tree = 0;
    g_scrollDirection_Tree = 0;
    if (tree.showHScrollBar) {
        let contentWidth = getTreeContentWidth(tree);
        if (contentWidth > 0 && contentWidth > tree.size.cx) {
            let sLeft = tree.scrollH / contentWidth * tree.size.cx;
            let sRight = (tree.scrollH + tree.size.cx) / contentWidth * tree.size.cx;
            if (sRight - sLeft < tree.scrollSize) {
                sRight = sLeft + tree.scrollSize;
            }
            if (mp.x >= sLeft && mp.x <= sRight && mp.y >= tree.size.cy - tree.scrollSize && mp.y <= tree.size.cy) {
                tree.downScrollHButton = true;
                tree.startScrollH = tree.scrollH;
                return;
            }
        }
    }
    if (tree.showVScrollBar) {
        let contentHeight = getTreeContentHeight(tree);
        if (contentHeight > 0 && contentHeight > tree.size.cy) {
            let sTop = tree.headerHeight + tree.scrollV / contentHeight * (tree.size.cy - tree.headerHeight - tree.scrollSize);
            let sBottom = tree.headerHeight + (tree.scrollV + (tree.size.cy - tree.headerHeight - tree.scrollSize)) / contentHeight * (tree.size.cy - tree.headerHeight - tree.scrollSize);
            if (sBottom - sTop < tree.scrollSize) {
                sBottom = sTop + tree.scrollSize;
            }
            if (mp.x >= tree.size.cx - tree.scrollSize && mp.x <= tree.size.cx && mp.y >= sTop && mp.y <= sBottom) {
                tree.downScrollVButton = true;
                tree.startScrollV = tree.scrollV;
                return;
            }
        }
    }
    if (tree.allowDragScroll) {
        tree.startScrollH = tree.scrollH;
        tree.startScrollV = tree.scrollV;
    }
}
let g_dragScrollView_Tree = null; //正在滚动的表格
let g_scrollAddSpeed_Tree = 0; //滚动加速
let g_scrollDirection_Tree = 0; //滚动方向
/*
* 检查拖动滚动
*/
function checkDragScroll_Tree() {
    if (g_dragScrollView_Tree) {
        let sub = Math.floor(g_scrollAddSpeed_Tree / 10);
        if (sub == 0 && g_scrollAddSpeed_Tree > 1) {
            sub = 1;
        }
        else if (sub == 0 && g_scrollAddSpeed_Tree < -1) {
            sub = -1;
        }
        g_scrollAddSpeed_Tree -= sub;
        if (Math.abs(sub) <= 1) {
            let viewCache = g_dragScrollView_Tree;
            g_scrollAddSpeed_Tree = 0;
            g_dragScrollView_Tree = null;
            if (viewCache.paint) {
                invalidateView(viewCache);
            }
        }
        else {
            let oldScrollV = Math.floor(g_dragScrollView_Tree.scrollV + g_scrollAddSpeed_Tree);
            let oldScrollH = Math.floor(g_dragScrollView_Tree.scrollH + g_scrollAddSpeed_Tree);
            if (g_scrollDirection_Tree == 0) {
                let contentHeight = getTreeContentHeight(g_dragScrollView_Tree);
                if (contentHeight < g_dragScrollView_Tree.size.cy) {
                    g_dragScrollView_Tree.scrollV = 0;
                }
                else {
                    if (oldScrollV < 0) {
                        oldScrollV = 0;
                    }
                    else if (oldScrollV > contentHeight - g_dragScrollView_Tree.size.cy + g_dragScrollView_Tree.headerHeight + g_dragScrollView_Tree.scrollSize) {
                        oldScrollV = contentHeight - g_dragScrollView_Tree.size.cy + g_dragScrollView_Tree.headerHeight + g_dragScrollView_Tree.scrollSize;
                    }
                    g_dragScrollView_Tree.scrollV = oldScrollV;
                }
            }
            else {
                let contentWidth = getTreeContentWidth(g_dragScrollView_Tree);
                if (contentWidth < g_dragScrollView_Tree.size.cx) {
                    g_dragScrollView_Tree.scrollH = 0;
                }
                else {
                    if (oldScrollH < 0) {
                        oldScrollH = 0;
                    }
                    else if (oldScrollH > contentWidth - g_dragScrollView_Tree.size.cx) {
                        oldScrollH = contentWidth - g_dragScrollView_Tree.size.cx;
                    }
                    g_dragScrollView_Tree.scrollH = oldScrollH;
                }
            }
            if (g_dragScrollView_Tree.paint) {
                invalidateView(g_dragScrollView_Tree);
            }
        }
    }
}
/*
* 表格的鼠标抬起方法
* tree: 树
* firstTouch:是否第一次触摸
* firstPoint:第一次触摸的坐标
* secondTouch:是否第二次触摸
* secondPoint:第二次触摸的坐标
* clicks:点击次数
*/
function touchUpTree(tree, firstTouch, firstPoint, secondTouch, secondPoint, clicks) {
    tree.hoverScrollHButton = false;
    tree.hoverScrollVButton = false;
    if (firstTouch && firstPoint && tree.startPoint && !tree.downScrollHButton && !tree.downScrollVButton) {
        if (tree.allowDragScroll) {
            let touchUpTime = new Date().getTime();
            let diff = touchUpTime - tree.touchDownTime;
            //加速滚动
            if (diff < 250) {
                let sub1 = 100 * ((Math.abs(firstPoint.y - tree.startPoint.y)) / 20) / diff * 10;
                let sub2 = 100 * ((Math.abs(firstPoint.x - tree.startPoint.x)) / 20) / diff * 10;
                if ("A:" + sub1 != "A:NaN" && "A:" + sub2 != "A:NaN") {
                    if (Math.abs(sub1) > Math.abs(sub2)) {
                        if (firstPoint.y < tree.startPoint.y) {
                            g_scrollAddSpeed_Tree += sub1;
                        }
                        else {
                            g_scrollAddSpeed_Tree -= sub1;
                        }
                        g_scrollDirection_Tree = 0;
                    }
                    else {
                        if (firstPoint.x < tree.startPoint.x) {
                            g_scrollAddSpeed_Tree += sub2;
                        }
                        else {
                            g_scrollAddSpeed_Tree -= sub2;
                        }
                        g_scrollDirection_Tree = 1;
                    }
                    g_dragScrollView_Tree = tree;
                    if (Math.abs(g_scrollAddSpeed_Tree) > 0) {
                        tree.paint.cancelClick = true;
                    }
                }
            }
        }
    }
    tree.downScrollHButton = false;
    tree.downScrollVButton = false;
    if (tree.paint.cancelClick) {
        return;
    }
    let cLeft = -tree.scrollH;
    let cTop = -tree.scrollV + tree.headerHeight;
    for (let i = 0; i < tree.rows.length; i++) {
        let row = tree.rows[i];
        if (row.visible) {
            if (firstPoint.y >= cTop && firstPoint.y <= cTop + tree.rowHeight) {
                let node = row.cells[0];
                let tLeft = cLeft + 2 + getTotalIndent(node);
                let wLeft = tLeft;
                for (let r = 0; r < tree.rows.length; r++) {
                    let subRow = tree.rows[r];
                    if (subRow == row) {
                        subRow.selected = true;
                    }
                    else {
                        subRow.selected = false;
                    }
                }
                if (tree.showCheckBox) {
                    wLeft += tree.checkBoxWidth;
                    if (firstPoint.x < wLeft) {
                        checkOrUnCheckTreeNode(node, !node.checked);
                        if (tree.paint) {
                            invalidateView(tree);
                        }
                        break;
                    }
                }
                if (node.childNodes.length > 0) {
                    wLeft += tree.collapsedWidth;
                    if (firstPoint.x < wLeft) {
                        node.collapsed = !node.collapsed;
                        hideOrShowTreeNode(node, !node.collapsed);
                        if (tree.paint) {
                            invalidateView(tree);
                        }
                        break;
                    }
                }
                if (tree.onClickTreeNode) {
                    tree.onClickTreeNode(tree, node, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
                }
                else if (tree.paint && tree.paint.onClickTreeNode) {
                    tree.paint.onClickTreeNode(tree, node, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
                }
            }
            cTop += tree.rowHeight;
        }
    }
}
/*
* 更新行的索引
* tree:树
*/
function updateTreeRowIndex(tree) {
    for (let i = 0; i < tree.rows.length; i++) {
        tree.rows[i].index = i;
    }
}
/*
* 获取最后一行的索引
* node:树节点
*/
function getTreeLastNodeRowIndex(node) {
    let rowIndex = node.row.index;
    for (let i = 0; i < node.childNodes.length; i++) {
        let rIndex = getTreeLastNodeRowIndex(node.childNodes[i]);
        if (rowIndex < rIndex) {
            rowIndex = rIndex;
        }
    }
    return rowIndex;
}
/*
* 添加节点
* tree:树
* node:要添加的节点
* parentNode:父节点
*/
function appendTreeNode(tree, node, parentNode) {
    if (!parentNode) {
        let newRow = new FCTreeRow();
        tree.rows.push(newRow);
        node.row = newRow;
        newRow.cells.push(node);
        tree.childNodes.push(node);
    }
    else {
        let newRow = new FCTreeRow();
        if (parentNode.childNodes.length == 0) {
            tree.rows.splice(parentNode.row.index + 1, 0, newRow);
        }
        else {
            tree.rows.splice(getTreeLastNodeRowIndex(parentNode) + 1, 0, newRow);
        }
        node.parentNode = parentNode;
        node.indent = tree.indent;
        node.row = newRow;
        newRow.cells.push(node);
        parentNode.childNodes.push(node);
        if (parentNode.collapsed) {
            newRow.visible = false;
        }
    }
    updateTreeRowIndex(tree);
}
/*
* 移除节点
* tree:树
* node:要添加的节点
*/
function removeTreeNode(tree, node) {
    //移除相互关系
    if (!node.parentNode) {
        let nodesSize = tree.childNodes.length;
        for (let i = 0; i < nodesSize; i++) {
            if (tree.childNodes[i] == node) {
                tree.childNodes.splice(i, 1);
                break;
            }
        }
    }
    else {
        let nodesSize = node.parentNode.childNodes.length;
        for (let i = 0; i < nodesSize; i++) {
            if (node.parentNode.childNodes[i] == node) {
                node.parentNode.childNodes.splice(i, 1);
                break;
            }
        }
    }
    //移除行
    tree.rows.splice(node.row.index, 1);
    updateTreeRowIndex(tree);
}
/*
* 展开或折叠节点
* node:节点
* visible:是否可见
*/
function hideOrShowTreeNode(node, visible) {
    if (node.childNodes.length > 0) {
        for (let i = 0; i < node.childNodes.length; i++) {
            node.childNodes[i].row.visible = visible;
            hideOrShowTreeNode(node.childNodes[i], visible);
        }
    }
}
/*
* 选中或反选节点
* node:节点
* checked:是否选中
*/
function checkOrUnCheckTreeNode(node, checked) {
    node.checked = checked;
    if (node.childNodes.length > 0) {
        for (let i = 0; i < node.childNodes.length; i++) {
            checkOrUnCheckTreeNode(node.childNodes[i], checked);
        }
    }
}
/*
*展开树的节点
*tree:树
*/
function expendTree(tree) {
    if (tree.childNodes.length > 0) {
        for (let i = 0; i < tree.childNodes.length; i++) {
            tree.childNodes[i].collapsed = false;
            hideOrShowTreeNode(tree.childNodes[i], true);
        }
    }
}
/*
*折叠树的节点
*tree:树
*/
function collapseTree(tree) {
    if (tree.childNodes.length > 0) {
        for (let i = 0; i < tree.childNodes.length; i++) {
            tree.childNodes[i].collapsed = true;
            hideOrShowTreeNode(tree.childNodes[i], false);
        }
    }
}
/*
* 树的鼠标滚轮方法
* tree:树
* delta:滚轮值
*/
function touchWheelTree(tree, delta) {
    let oldScrollV = tree.scrollV;
    if (delta < 0) {
        oldScrollV -= 20;
    }
    else if (delta > 0) {
        oldScrollV += 20;
    }
    let contentHeight = getTreeContentHeight(tree);
    if (contentHeight < tree.size.cy) {
        tree.scrollV = 0;
    }
    else {
        if (oldScrollV < 0) {
            oldScrollV = 0;
        }
        else if (oldScrollV > contentHeight - tree.size.cy + tree.headerHeight + tree.scrollSize) {
            oldScrollV = contentHeight - tree.size.cy + tree.headerHeight + tree.scrollSize;
        }
        tree.scrollV = oldScrollV;
    }
}
/*
 * 自动适应位置和大小
 * menu:菜单
 */
function adjustMenu(menu) {
    resetLayoutDiv(menu);
    if (menu.autoSize) {
        let contentHeight = getDivContentHeight(menu);
        let maximumHeight = menu.maximumSize.cy;
        menu.size.cy = Math.min(contentHeight, maximumHeight);
    }
    let mPoint = menu.location;
    let mSize = menu.size;
    let paint = menu.paint;
    let nSize = new FCSize((paint.canvas.width / paint.ratio / paint.scaleFactorX), (paint.canvas.height / paint.ratio / paint.scaleFactorY));
    if (mPoint.x < 0) {
        mPoint.x = 0;
    }
    if (mPoint.y < 0) {
        mPoint.y = 0;
    }
    if (mPoint.x + mSize.cx > nSize.cx) {
        mPoint.x = nSize.cx - mSize.cx;
    }
    if (mPoint.y + mSize.cy > nSize.cy) {
        mPoint.y = nSize.cy - mSize.cy;
    }
    menu.location = mPoint;
    menu.scrollV = 0;
}
/*
 * 添加菜单项
 * item:菜单项
 * menu:菜单
 */
function addMenuItem(item, menu) {
    addViewToParent(item, menu);
    item.parentMenu = menu;
    menu.items.push(item);
}
/*
 * 添加菜单项
 * item:菜单项
 * parentItem:父菜单项
 */
function addMenuItemToParent(item, parentItem) {
    item.parentItem = parentItem;
    if (!parentItem.dropDownMenu) {
        parentItem.dropDownMenu = new FCMenu();
        addView(parentItem.dropDownMenu, parentItem.paint);
    }
    item.parentMenu = parentItem.dropDownMenu;
    addViewToParent(item, parentItem.dropDownMenu);
    parentItem.items.push(item);
    parentItem.dropDownMenu.items.push(item);
}
/*
 * 控制菜单的显示隐藏
 * paint:绘图对象
 */
function checkShowMenu(paint) {
    let paintAll = false;
    let clickItem = false;
    for (let i = 0; i < paint.views.length; i++) {
        let view = paint.views[i];
        if (view.viewType == "menu") {
            let menu = view;
            if (view.visible) {
                if (view == paint.touchDownView) {
                    clickItem = true;
                }
                for (let j = 0; j < menu.items.length; j++) {
                    let item = menu.items[j];
                    if (item == paint.touchDownView) {
                        clickItem = true;
                        break;
                    }
                }
            }
        }
    }
    if (!clickItem) {
        for (let i = 0; i < paint.views.length; i++) {
            let view = paint.views[i];
            if (view.viewType == "menu") {
                view.visible = false;
                paintAll = true;
            }
        }
    }
    if (paintAll) {
        invalidate(paint);
    }
}
/*
 * 关闭网格视图
 * items:菜单集合
 */
function closeMenus(items) {
    let itemSize = items.length;
    let close = false;
    for (let i = 0; i < itemSize; i++) {
        let item = items[i];
        let subItems = item.items;
        if (closeMenus(subItems)) {
            close = true;
        }
        let dropDownMenu = item.dropDownMenu;
        if (dropDownMenu && dropDownMenu.visible) {
            dropDownMenu.visible = false;
            close = true;
        }
    }
    return close;
}
/*
 * 鼠标移动到菜单项
 * item 菜单项
 */
function touchMoveMenuItem(item) {
    let parentItem = item.parentItem;
    let items = [];
    if (parentItem) {
        if (parentItem.dropDownMenu) {
            items = parentItem.dropDownMenu.items;
        }
    }
    else {
        if (item.parentMenu) {
            items = item.parentMenu.items;
        }
    }
    closeMenus(items);
    if (item.items.length > 0) {
        let dropDownMenu = item.dropDownMenu;
        //获取位置和大小
        if (dropDownMenu && !dropDownMenu.visible) {
            let layoutStyle = dropDownMenu.layoutStyle;
            let location = new FCPoint(clientX(item) + item.size.cx, clientY(item));
            if (layoutStyle == "lefttoright" || layoutStyle == "righttoleft") {
                location.x = clientX(item);
                location.y = clientY(item) + item.size.cy;
            }
            //设置弹出位置
            dropDownMenu.location = location;
            dropDownMenu.visible = true;
            adjustMenu(dropDownMenu);
            invalidate(item.paint);
            return;
        }
    }
    invalidate(item.paint);
}
;
/*
* 重绘按钮
* item:菜单项
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawMenuItem(item, paint, clipRect) {
    if (item == paint.touchDownView) {
        if (item.pushedColor && item.pushedColor != "nne") {
            paint.fillRect(item.pushedColor, 0, 0, item.size.cx, item.size.cy);
        }
        else {
            if (item.backColor && item.backColor != "none") {
                paint.fillRect(item.backColor, 0, 0, item.size.cx, item.size.cy);
            }
        }
    }
    else if (item == paint.touchMoveView) {
        if (item.hoveredColor && item.hoveredColor != "none") {
            paint.fillRect(item.hoveredColor, 0, 0, item.size.cx, item.size.cy);
        }
        else {
            if (item.backColor && item.backColor != "none") {
                paint.fillRect(item.backColor, 0, 0, item.size.cx, item.size.cy);
            }
        }
    }
    else if (item.backColor && item.backColor != "none") {
        paint.fillRect(item.backColor, 0, 0, item.size.cx, item.size.cy);
    }
    if (item.textColor && item.textColor != "none" && item.text) {
        let tSize = paint.textSize(item.text, item.font);
        paint.drawText(item.text, item.textColor, item.font, (item.size.cx - tSize.cx) / 2, item.size.cy / 2 + 1 - tSize.cy / 2);
    }
    if (item.borderColor && item.borderColor != "none") {
        paint.drawRect(item.borderColor, item.borderWidth, [], 0, 0, item.size.cx, item.size.cy);
    }
    if (item.items.length > 0) {
        let tR = 5;
        paint.beginPath();
        paint.addLine(item.size.cx - 2, item.size.cy / 2, item.size.cx - 2 - tR * 2, item.size.cy / 2 - tR);
        paint.addLine(item.size.cx - 2 - tR * 2, item.size.cy / 2 - tR, item.size.cx - 2 - tR * 2, item.size.cy / 2 + tR);
        paint.addLine(item.size.cx - 2 - tR * 2, item.size.cy / 2 + tR, item.size.cx - 2, item.size.cy / 2);
        paint.fillPath(item.textColor);
        paint.closePath();
    }
}
/*
 * 点击菜单项
 * item:菜单项
 */
function clickMenuItem(item) {
    let paintAll = false;
    if (item.parentMenu) {
        if (item.parentMenu.comboBox) {
            let index = -1;
            for (let i = 0; i < item.parentMenu.items.length; i++) {
                if (item.parentMenu.items[i] == item) {
                    index = i;
                    break;
                }
            }
            item.parentMenu.comboBox.selectedIndex = index;
            item.parentMenu.comboBox.text = item.parentMenu.items[index].text;
            paintAll = true;
        }
    }
    if (item.items.length == 0) {
        for (let i = 0; i < item.paint.views.length; i++) {
            let subView = item.paint.views[i];
            if (subView.viewType == "menu") {
                if (subView.visible) {
                    subView.visible = false;
                    paintAll = true;
                }
            }
        }
    }
    if (paintAll) {
        invalidate(item.paint);
    }
}
/*
* 重绘按钮
* comboBox:下拉列表
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawComboBox(comboBox, paint, clipRect) {
    if (comboBox.backColor && comboBox.backColor != "none") {
        paint.fillRect(comboBox.backColor, 0, 0, comboBox.size.cx, comboBox.size.cy);
    }
    if (comboBox.textColor && comboBox.textColor != "none" && comboBox.text) {
        let tSize = paint.textSize(comboBox.text, comboBox.font);
        paint.drawText(comboBox.text, comboBox.textColor, comboBox.font, 5, comboBox.size.cy / 2 + 1 - tSize.cy / 2);
    }
    if (comboBox.borderColor && comboBox.borderColor != "none") {
        paint.drawRect(comboBox.borderColor, comboBox.borderWidth, [], 0, 0, comboBox.size.cx, comboBox.size.cy);
    }
    let tR = 5;
    paint.beginPath();
    paint.addLine(comboBox.size.cx - 5 - tR * 2, comboBox.size.cy / 2 - tR, comboBox.size.cx - 5, comboBox.size.cy / 2 - tR);
    paint.addLine(comboBox.size.cx - 5, comboBox.size.cy / 2 - tR, comboBox.size.cx - 5 - tR, comboBox.size.cy / 2 + tR);
    paint.addLine(comboBox.size.cx - 5 - tR, comboBox.size.cy / 2 + tR, comboBox.size.cx - 5 - tR * 2, comboBox.size.cy / 2 - tR);
    paint.fillPath(comboBox.textColor);
    paint.closePath();
}
/*
 * 点击下拉菜单
 * comboBox:下拉菜单
 */
function clickComboBox(comboBox) {
    let showX = clientX(comboBox);
    let showY = clientY(comboBox) + comboBox.size.cy;
    comboBox.dropDownMenu.location = new FCPoint(showX, showY);
    comboBox.dropDownMenu.visible = true;
    adjustMenu(comboBox.dropDownMenu);
    invalidate(comboBox.paint);
}
/*
* 格式化字符串
* fmt:格式化字符
* date:日期
*/
function dateFormat(fmt, date) {
    let year = date.getFullYear();
    let month = date.getMonth() + 1;
    let day = date.getDay();
    let hour = date.getHours();
    let minute = date.getMinutes();
    let second = date.getSeconds();
    let formatStr = fmt.replace("YYYY", year.toString());
    if (month < 10) {
        formatStr = formatStr.replace("mm", "0" + month.toString());
    }
    else {
        formatStr = formatStr.replace("mm", month.toString());
    }
    if (month < 10) {
        formatStr = formatStr.replace("dd", "0" + day.toString());
    }
    else {
        formatStr = formatStr.replace("dd", day.toString());
    }
    if (hour < 10) {
        formatStr = formatStr.replace("HH", "0" + hour.toString());
    }
    else {
        formatStr = formatStr.replace("HH", hour.toString());
    }
    if (minute < 10) {
        formatStr = formatStr.replace("MM", "0" + minute.toString());
    }
    else {
        formatStr = formatStr.replace("MM", minute.toString());
    }
    if (second < 10) {
        formatStr = formatStr.replace("SS", "0" + second.toString());
    }
    else {
        formatStr = formatStr.replace("SS", second.toString());
    }
    return formatStr;
}
/*
* 计算直线参数
* mp:坐标
* x1:横坐标1
* y1:纵坐标1
* x2:横坐标2
* y2:纵坐标2
* oX:坐标起始X
* oY:坐标起始Y
*/
function lineXY(chart, x1, y1, x2, y2, oX, oY) {
    chart.kChart = 0;
    chart.bChart = 0;
    if ((x1 - oX) != (x2 - oX)) {
        chart.kChart = ((y2 - oY) - (y1 - oY)) / ((x2 - oX) - (x1 - oX));
        chart.bChart = (y1 - oY) - chart.kChart * (x1 - oX);
    }
}
/*
* 判断是否选中直线
* mp:坐标
* x1:横坐标1
* y1:纵坐标1
* x2:横坐标2
* y2:纵坐标2
*/
function selectLine(chart, mp, x1, y1, x2, y2) {
    lineXY(chart, x1, y1, x2, y2, 0, 0);
    if (!(chart.kChart == 0 && chart.bChart == 0)) {
        if (mp.y / (mp.x * chart.kChart + chart.bChart) >= 0.9 && mp.y / (mp.x * chart.kChart + chart.bChart) <= 1.1) {
            return true;
        }
    }
    else {
        if (mp.x >= x1 - chart.plotPointSizeChart && mp.x <= x1 + chart.plotPointSizeChart) {
            return true;
        }
    }
    return false;
}
/*
* 判断是否选中射线
* mp:坐标
* x1:横坐标1
* y1:纵坐标1
* x2:横坐标2
* y2:纵坐标2
*/
function selectRay(chart, mp, x1, y1, x2, y2) {
    lineXY(chart, x1, y1, x2, y2, 0, 0);
    if (!(chart.kChart == 0 && chart.bChart == 0)) {
        if (mp.y / (mp.x * chart.kChart + chart.bChart) >= 0.9 && mp.y / (mp.x * chart.kChart + chart.bChart) <= 1.1) {
            if (x1 >= x2) {
                if (mp.x > x1 + chart.plotPointSizeChart) {
                    return false;
                }
            }
            else if (x1 < x2) {
                if (mp.x < x1 - chart.plotPointSizeChart) {
                    return false;
                }
            }
            return true;
        }
    }
    else {
        if (mp.x >= x1 - chart.plotPointSizeChart && mp.x <= x1 + chart.plotPointSizeChart) {
            if (y1 >= y2) {
                if (mp.y <= y1 - chart.plotPointSizeChart) {
                    return true;
                }
            }
            else {
                if (mp.y >= y1 - chart.plotPointSizeChart) {
                    return true;
                }
            }
        }
    }
    return false;
}
/*
* 判断是否选中线段
* mp:坐标
* x1:横坐标1
* y1:纵坐标1
* x2:横坐标2
* y2:纵坐标2
*/
function selectSegment(chart, mp, x1, y1, x2, y2) {
    lineXY(chart, x1, y1, x2, y2, 0, 0);
    let smallX = x1 <= x2 ? x1 : x2;
    let smallY = y1 <= y2 ? y1 : y2;
    let bigX = x1 > x2 ? x1 : x2;
    let bigY = y1 > y2 ? y1 : y2;
    if (mp.x >= smallX - 2 && mp.x <= bigX + 2 && mp.y >= smallY - 2 && mp.y <= bigY + 2) {
        if (chart.kChart != 0 || chart.bChart != 0) {
            if (mp.y / (mp.x * chart.kChart + chart.bChart) >= 0.9 && mp.y / (mp.x * chart.kChart + chart.bChart) <= 1.1) {
                return true;
            }
        }
        else {
            if (mp.x >= x1 - chart.plotPointSizeChart && mp.x <= x1 + chart.plotPointSizeChart) {
                return true;
            }
        }
    }
    return false;
}
/*
* 根据三点计算圆心
* x1:横坐标1
* y1:纵坐标1
* x2:横坐标2
* y2:纵坐标2
* x3:横坐标3
* y3:纵坐标3
*/
function ellipseOR(chart, x1, y1, x2, y2, x3, y3) {
    chart.oXChart = ((y3 - y1) * (y2 * y2 - y1 * y1 + x2 * x2 - x1 * x1) + (y2 - y1) * (y1 * y1 - y3 * y3 + x1 * x1 - x3 * x3))
        / (2 * (x2 - x1) * (y3 - y1) - 2 * (x3 - x1) * (y2 - y1));
    chart.oYChart = ((x3 - x1) * (x2 * x2 - x1 * x1 + y2 * y2 - y1 * y1) + (x2 - x1) * (x1 * x1 - x3 * x3 + y1 * y1 - y3 * y3))
        / (2 * (y2 - y1) * (x3 - x1) - 2 * (y3 - y1) * (x2 - x1));
    chart.rChart = Math.sqrt((x1 - chart.oXChart) * (x1 - chart.oXChart) + (y1 - chart.oYChart) * (y1 - chart.oYChart));
}
/*
* 判断点是否在椭圆上
* x:横坐标
* y:纵坐标
* oX:坐标起始X
* oY:坐标起始Y
* a:椭圆参数a
* b:椭圆参数b
*/
function ellipseHasPoint(x, y, oX, oY, a, b) {
    x -= oX;
    y -= oY;
    if (a == 0 && b == 0 && x == 0 && y == 0) {
        return true;
    }
    if (a == 0) {
        if (x == 0 && y >= -b && y <= b) {
            return false;
        }
    }
    if (b == 0) {
        if (y == 0 && x >= -a && x <= a) {
            return true;
        }
    }
    if ((x * x) / (a * a) + (y * y) / (b * b) >= 0.8 && (x * x) / (a * a) + (y * y) / (b * b) <= 1.2) {
        return true;
    }
    return false;
}
/*
* 计算线性回归
* list:集合
*/
function linearRegressionEquation(chart, list) {
    let result = 0;
    let sumX = 0;
    let sumY = 0;
    let sumUp = 0;
    let sumDown = 0;
    let xAvg = 0;
    let yAvg = 0;
    chart.kChart = 0;
    chart.bChart = 0;
    let length = list.length;
    let i = 0;
    if (length > 1) {
        for (i = 0; i < length; i++) {
            sumX += i + 1;
            sumY += list[i];
        }
        xAvg = sumX / length;
        yAvg = sumY / length;
        for (i = 0; i < length; i++) {
            sumUp += (i + 1 - xAvg) * (list[i] - yAvg);
            sumDown += (i + 1 - xAvg) * (i + 1 - xAvg);
        }
        chart.kChart = sumUp / sumDown;
        chart.bChart = yAvg - chart.kChart * xAvg;
    }
    return result;
}
/*
* 计算最大值
* list:集合
*/
function maxValue(list) {
    let length = list.length;
    let max = 0;
    for (let i = 0; i < length; i++) {
        if (i == 0) {
            max = list[i];
        }
        else {
            if (max < list[i]) {
                max = list[i];
            }
        }
    }
    return max;
}
/*
* 计算最小值
* list:集合
*/
function minValue(list) {
    let length = list.length;
    let min = 0;
    for (let i = 0; i < length; i++) {
        if (i == 0) {
            min = list[i];
        }
        else {
            if (min > list[i]) {
                min = list[i];
            }
        }
    }
    return min;
}
/*
* 计算平均值
* list:集合
*/
function avgValue(list) {
    let sum = 0;
    let length = list.length;
    if (length > 0) {
        for (let i = 0; i < length; i++) {
            sum += list[i];
        }
        return sum / length;
    }
    return 0;
}
/*
* 计算平行四边形参数
* x1:横坐标1
* y1:纵坐标1
* x2:横坐标2
* y2:纵坐标2
* x3:横坐标3
* y3:纵坐标3
*/
function parallelogram(chart, x1, y1, x2, y2, x3, y3) {
    chart.x4Chart = x1 + x3 - x2;
    chart.y4Chart = y1 + y3 - y2;
}
/*
* 计算斐波那契数列
* index:索引
*/
function fibonacciValue(index) {
    if (index < 1) {
        return 0;
    }
    else {
        let vList = [];
        for (let i = 0; i < index; i++) {
            vList.push(0);
        }
        let result = 0;
        for (let i = 0; i <= index - 1; i++) {
            if (i == 0 || i == 1) {
                vList[i] = 1;
            }
            else {
                vList[i] = vList[i - 1] + vList[i - 2];
            }
        }
        result = vList[index - 1];
        return result;
    }
}
/*
* 获取图表的区域
* chart: 图表
* plot: 画线
*/
function getCandleRange(chart, plot) {
    let bIndex = getChartIndexByDate(chart, plot.key1);
    let eIndex = getChartIndexByDate(chart, plot.key2);
    let tempBIndex = Math.min(bIndex, eIndex);
    let tempEIndex = Math.max(bIndex, eIndex);
    bIndex = tempBIndex;
    eIndex = tempEIndex;
    let highList = [];
    let lowList = [];
    for (let i = bIndex; i <= eIndex; i++) {
        highList.push(chart.data[i].high);
        lowList.push(chart.data[i].low);
    }
    chart.nHighChart = maxValue(highList);
    chart.nLowChart = minValue(lowList);
}
/*
* 获取百分比线的刻度
* y1: 纵坐标1
* y2: 纵坐标2
*/
function getPercentParams(y1, y2) {
    let list = [];
    let y0 = 0, y25 = 0, y50 = 0, y75 = 0, y100 = 0;
    y0 = y1;
    y25 = y1 <= y2 ? y1 + (y2 - y1) / 4 : y2 + (y1 - y2) * 3 / 4;
    y50 = y1 <= y2 ? y1 + (y2 - y1) / 2 : y2 + (y1 - y2) / 2;
    y75 = y1 <= y2 ? y1 + (y2 - y1) * 3 / 4 : y2 + (y1 - y2) / 4;
    y100 = y2;
    list.push(y0);
    list.push(y25);
    list.push(y50);
    list.push(y75);
    list.push(y100);
    return list;
}
/*
* 根据坐标计算矩形
* x1:横坐标1
* y1:纵坐标1
* x2:横坐标2
* y2:纵坐标2
*/
function rectangleXYWH(chart, x1, y1, x2, y2) {
    chart.xChart = x1 < x2 ? x1 : x2;
    chart.yChart = y1 < y2 ? y1 : y2;
    chart.wChart = x1 - x2 > 0 ? x1 - x2 : x2 - x1;
    chart.hChart = y1 - y2 > 0 ? y1 - y2 : y2 - y1;
    if (chart.wChart <= 0) {
        chart.wChart = 4;
    }
    if (chart.hChart <= 0) {
        chart.hChart = 4;
    }
}
/*
 * 计算最大值
 * @param {Object} ticks 最高价数组
 * @param {Object} days
 */
function hhvValue(ticks, days) {
    let hhv = [];
    let max = ticks[0];
    for (let i = 0; i < ticks.length; i++) {
        if (i >= days) {
            max = ticks[i];
            for (let j = i; j > i - days; j--) {
                if (max < ticks[j]) {
                    max = ticks[j];
                }
            }
            hhv.push(max);
        }
        else {
            if (max < ticks[i]) {
                max = ticks[i];
            }
            hhv.push(max);
        }
    }
    return hhv;
}
/*
 * 计算最小值
 * @param {Object} ticks 最低价数组
 * @param {Object} days
 */
function llvValue(ticks, days) {
    let llv = [];
    let min = ticks[0];
    for (let i = 0; i < ticks.length; i++) {
        if (i >= days) {
            min = ticks[i];
            for (let j = i; j > i - days; j--) {
                if (min > ticks[j]) {
                    min = ticks[j];
                }
            }
            llv.push(min);
        }
        else {
            if (min > ticks[i]) {
                min = ticks[i];
            }
            llv.push(min);
        }
    }
    return llv;
}
/*
* REF函数
* ticks:数据
* days:日数
*/
function refValue(ticks, days) {
    let refArr = [];
    let length = ticks.length;
    for (let i = 0; i < length; i++) {
        let ref = 0;
        if (i >= days) {
            ref = ticks[i - days];
        }
        else {
            ref = ticks[0];
        }
        refArr.push(ref);
    }
    return refArr;
}
/*
* 获取TRIX的数据
* ticks:数据
*/
function getTRIXData(ticks, m, trixArr, matrixArr) {
    let length = ticks.length;
    let mtrArr = [];
    let emaArr1 = [];
    emaArr1.push(ticks[0]);
    for (let i = 1; i < length; i++) {
        emaArr1.push(getEMA(m, ticks[i], emaArr1[i - 1]));
    }
    let emaArr2 = [];
    emaArr2.push(emaArr1[0]);
    for (let i = 1; i < length; i++) {
        emaArr2.push(getEMA(m, emaArr1[i], emaArr2[i - 1]));
    }
    mtrArr.push(emaArr2[0]);
    for (let i = 1; i < length; i++) {
        mtrArr.push(getEMA(m, emaArr2[i], mtrArr[i - 1]));
    }
    let ref = refValue(mtrArr, 1);
    for (let i = 0; i < length; i++) {
        let trix = 100 * (mtrArr[i] - ref[i]) / ref[i];
        trixArr.push(trix);
    }
    let matrixArrCopy = maValue(trixArr, m);
    for (let i = 0; i < matrixArrCopy.length; i++) {
        matrixArr.push(matrixArrCopy[i]);
    }
}
/*
* 获取方差数据
*/
function standardDeviationSum(listValue, avgValue) {
    let targetValue = listValue[listValue.length - 1];
    let sumValue = (targetValue - avgValue) * (targetValue - avgValue);
    for (let i = 0; i < listValue.length - 1; i++) {
        let ileft = listValue[i];
        sumValue = sumValue + (ileft - avgValue) * (ileft - avgValue);
    }
    return sumValue;
}
/*
 * 计算boll指标,ma的周期为20日
 *
 * @method BOLL
 * @param {Array} ticks
 * 一维数组类型，每个元素为当前Tick的收盘价格
 * @return {Object} 返回一个包含upper mid lower属性的对象,每个属性对应的类型为{Array[Number]}
 */
function getBollData(ticks, maDays, ups, mas, lows) {
    let tickBegin = maDays - 1;
    let maSum = 0;
    let p = 0;
    for (let i = 0; i < ticks.length; i++) {
        let c = ticks[i];
        let ma = 0;
        let md = 0;
        let bstart = 0;
        let mdSum = 0;
        maSum = maSum + c;
        if (i >= tickBegin) {
            maSum = maSum - p;
            ma = maSum / maDays;
            bstart = i - tickBegin;
            p = ticks[bstart];
            mas.push(ma);
            bstart = i - tickBegin;
            p = ticks[bstart];
            let values = [];
            for (let j = bstart; j < bstart + maDays; j++) {
                values.push(ticks[j]);
            }
            mdSum = standardDeviationSum(values, ma);
            md = Math.sqrt(mdSum / maDays);
            ups.push(ma + 2 * md);
            lows.push(ma - 2 * md);
        }
        else {
            ma = maSum / (i + 1);
            mas.push(ma);
            let values = [];
            for (let j = 0; j < i + 1; j++) {
                values.push(ticks[j]);
            }
            mdSum = standardDeviationSum(values, ma);
            md = Math.sqrt(mdSum / (i + 1));
            ups.push(ma + 2 * md);
            lows.push(ma - 2 * md);
        }
    }
}
/*
 *
 * 计算kdj指标,rsv的周期为9日
 *
 * @method KDJ
 * @param {Array} ticks
 * 二维数组类型，其中内层数组包含三个元素值，第一个值表示当前Tick的最高价格，第二个表示当前Tick的最低价格，第三个表示当前Tick的收盘价格
 * @return {Object} 返回一个包含k d j属性的对象,每个属性对应的类型为{Array[Number]}
 */
function getKDJData(highArr, lowArr, closeArr, n, m1, m2, ks, ds, js) {
    let rsvs = [];
    let lastK = 0;
    let lastD = 0;
    let curK = 0;
    let curD = 0;
    for (let i = 0; i < closeArr.length; i++) {
        let highList = [];
        let lowList = [];
        let startIndex = i - n;
        if (startIndex < 0) {
            startIndex = 0;
        }
        for (let j = startIndex; j <= i; j++) {
            highList.push(highArr[j]);
            lowList.push(lowArr[j]);
        }
        let close = closeArr[i];
        let maxHigh = 0, minLow = 0;
        for (let m = 0; m < highList.length; m++) {
            let high = highList[m];
            let low = lowList[m];
            if (high > maxHigh) {
                maxHigh = high;
            }
            if (low < minLow) {
                minLow = low;
            }
        }
        if (maxHigh == minLow) {
            rsvs.push(0);
        }
        else {
            rsvs.push((close - minLow) / (maxHigh - minLow) * 100);
        }
        if (i == 0) {
            lastK = rsvs[i];
            lastD = rsvs[i];
        }
        curK = (m1 - 1) / m1 * lastK + 1.0 / m1 * rsvs[i];
        ks.push(curK);
        lastK = curK;
        curD = (m2 - 1) / m2 * lastD + 1.0 / m2 * curK;
        ds.push(curD);
        lastD = curD;
        js.push(3.0 * curK - 2.0 * curD);
    }
}
/*
 *
 * 计算rsi指标,分别返回以6日，12日，24日为参考基期的RSI值
 *
 * @method RSI
 * @param {Array} ticks
 * 一维数组类型，每个元素为当前Tick的收盘价格
 * @return {Object} 返回一个包含rsi6 rsi12 rsi24属性的对象,每个属性对应的类型为{Array[Number]}
 */
function getRSIData(ticks, n1, n2, n3, rsi1, rsi2, rsi3) {
    let lastClosePx = ticks[0];
    let lastSm1 = 0;
    let lastSa1 = 0;
    let lastSm2 = 0;
    let lastSa2 = 0;
    let lastSm3 = 0;
    let lastSa3 = 0;
    for (let i = 0; i < ticks.length; i++) {
        let c = ticks[i];
        let m = Math.max(c - lastClosePx, 0);
        let a = Math.abs(c - lastClosePx);
        if (i == 0) {
            lastSm1 = 0;
            lastSa1 = 0;
            rsi1.push(0);
        }
        else {
            lastSm1 = (m + (n1 - 1) * lastSm1) / n1;
            lastSa1 = (a + (n1 - 1) * lastSa1) / n1;
            if (lastSa1 != 0) {
                rsi1.push(lastSm1 / lastSa1 * 100);
            }
            else {
                rsi1.push(0);
            }
        }
        if (i == 0) {
            lastSm2 = 0;
            lastSa2 = 0;
            rsi2.push(0);
        }
        else {
            lastSm2 = (m + (n2 - 1) * lastSm2) / n2;
            lastSa2 = (a + (n2 - 1) * lastSa2) / n2;
            if (lastSa2 != 0) {
                rsi2.push(lastSm2 / lastSa2 * 100);
            }
            else {
                rsi2.push(0);
            }
        }
        if (i == 0) {
            lastSm3 = 0;
            lastSa3 = 0;
            rsi3.push(0);
        }
        else {
            lastSm3 = (m + (n3 - 1) * lastSm3) / n3;
            lastSa3 = (a + (n3 - 1) * lastSa3) / n3;
            if (lastSa3 != 0) {
                rsi3.push(lastSm3 / lastSa3 * 100);
            }
            else {
                rsi3.push(0.0);
            }
        }
        lastClosePx = c;
    }
}
/*
 * MA数据计算
 * @param {Object} ticks 收盘价数组
 * @param {Object} days 天数
 */
function maValue(ticks, days) {
    let maSum = 0;
    let mas = [];
    let last = 0;
    for (let i = 0; i < ticks.length; i++) {
        let ma = 0;
        if (i >= days) {
            last = ticks[i - days];
            maSum = maSum + ticks[i] - last;
            ma = maSum / days;
        }
        else {
            maSum += ticks[i];
            ma = maSum / (i + 1);
        }
        mas.push(ma);
    }
    return mas;
}
/*
 * 计算ROC数据
 * @param {Object} ticks 收盘价数组
 */
function getRocData(ticks, n, m, roc, maroc) {
    for (let i = 0; i < ticks.length; i++) {
        let currRoc = 0;
        if (i >= n) {
            currRoc = 100 * (ticks[i] - ticks[i - n]) / ticks[i - n];
            roc.push(currRoc);
        }
        else {
            currRoc = 100 * (ticks[i] - ticks[0]) / ticks[0];
            roc.push(currRoc);
        }
    }
    let marocMA = maValue(roc, m);
    for (let i = 0; i < marocMA.length; i++) {
        maroc.push(marocMA[i]);
    }
}
/*
 * 获取BIAS的数据
 * @param {Array} ticks 收盘价数组
 * @return
 */
function getBIASData(ticks, n1, n2, n3, bias1Arr, bias2Arr, bias3Arr) {
    let ma1 = maValue(ticks, n1);
    let ma2 = maValue(ticks, n2);
    let ma3 = maValue(ticks, n3);
    for (let i = 0; i < ticks.length; i++) {
        let b1 = (ticks[i] - ma1[i]) / ma1[i] * 100;
        let b2 = (ticks[i] - ma2[i]) / ma2[i] * 100;
        let b3 = (ticks[i] - ma3[i]) / ma3[i] * 100;
        bias1Arr.push(b1);
        bias2Arr.push(b2);
        bias3Arr.push(b3);
    }
}
/*
 * 计算BBI(多空指标)
 * @param {Object} ticks
 */
function getBBIData(ticks, n1, n2, n3, n4, bbiArr) {
    let ma3 = maValue(ticks, n1);
    let ma6 = maValue(ticks, n2);
    let ma12 = maValue(ticks, n3);
    let ma24 = maValue(ticks, n4);
    for (let i = 0; i < ticks.length; i++) {
        let bbi = (ma3[i] + ma6[i] + ma12[i] + ma24[i]) / 4;
        bbiArr.push(bbi);
    }
}
/*
 * 计算WR(威廉指标)
 * @param {Array} ticks 含最高价,最低价, 收盘价的二维数组
 * @param {Object} days
 */
function getWRData(highArr, lowArr, closeArr, n1, n2, wr1Arr, wr2Arr) {
    let highArr1 = hhvValue(highArr, n1);
    let highArr2 = hhvValue(highArr, n2);
    let lowArr1 = llvValue(lowArr, n1);
    let lowArr2 = llvValue(lowArr, n2);
    for (let i = 0; i < closeArr.length; i++) {
        let high1 = highArr1[i];
        let low1 = lowArr1[i];
        let high2 = highArr2[i];
        let low2 = lowArr2[i];
        let close = closeArr[i];
        let wr1 = 100 * (high1 - close) / (high1 - low1);
        let wr2 = 100 * (high2 - close) / (high2 - low2);
        wr1Arr.push(wr1);
        wr2Arr.push(wr2);
    }
}
/*
 * 计算DMA（平均差）
 * @param {Object} ticks 收盘价数组
 */
function getDMAData(ticks, n1, n2, difArr, difmaArr) {
    let ma10 = maValue(ticks, n1);
    let ma50 = maValue(ticks, n2);
    for (let i = 0; i < ticks.length; i++) {
        let dif = ma10[i] - ma50[i];
        difArr.push(dif);
    }
    let difma = maValue(difArr, n1);
    for (let i = 0; i < difma.length; i++) {
        difmaArr.push(difma[i]);
    }
}
/*
 * CCI(顺势指标)计算  CCI（N日）=（TP－MA）÷MD÷0.015
 * @param {Object} ticks 带最高价，最低价，收盘价的二维数组
 */
function getCCIData(highArr, lowArr, closeArr, n, cciArr) {
    let tpArr = [];
    for (let i = 0; i < closeArr.length; i++) {
        tpArr.push((closeArr[i] + highArr[i] + lowArr[i]) / 3);
    }
    let maClose = maValue(closeArr, n);
    let mdArr = [];
    for (let i = 0; i < closeArr.length; i++) {
        mdArr.push(maClose[i] - closeArr[i]);
    }
    let maMD = maValue(mdArr, n);
    for (let i = 0; i < closeArr.length; i++) {
        let cci = 0;
        if (maMD[i] > 0) {
            cci = (tpArr[i] - maClose[i]) / (maMD[i] * 0.015);
        }
        cciArr.push(cci);
    }
}
/*
* 图表的鼠标按下方法
* chart: 图表
* firstTouch:是否第一次触摸
* firstPoint:第一次触摸的坐标
* secondTouch:是否第二次触摸
* secondPoint:第二次触摸的坐标
*/
function touchDownChart(chart, firstTouch, firstPoint, secondTouch, secondPoint) {
    let mp = firstPoint;
    chart.touchDownPointChart = mp;
    chart.targetOldX = 0;
    chart.targetOldX2 = 0;
    chart.crossStopIndex = getChartIndex(chart, mp);
    chart.selectShape = "";
    chart.selectShapeEx = "";
    if (chart.data && chart.data.length > 0) {
        chart.sPlot = selectPlot(chart, mp);
        if (!chart.sPlot) {
            selectShape(chart, mp);
        }
    }
    if (chart.paint.isDoubleClick) {
        chart.showCrossLine = !chart.showCrossLine;
    }
}
/*
*左滚
*chart:图表
*step:步长
*/
function scrollLeftChart(chart, step) {
    chart.targetOldX = 0;
    chart.targetOldX2 = 0;
    if (chart.showCrossLine) {
        chart.crossStopIndex = chart.crossStopIndex - step;
        if (chart.crossStopIndex >= chart.firstVisibleIndex) {
            step = 0;
        }
        else if (chart.crossStopIndex < 0) {
            chart.crossStopIndex = 0;
        }
    }
    if (step > 0) {
        let subIndex = chart.lastVisibleIndex - chart.firstVisibleIndex;
        let fIndex = chart.firstVisibleIndex - step;
        if (fIndex < 0) {
            fIndex = 0;
        }
        let eIndex = fIndex + subIndex;
        chart.firstVisibleIndex = fIndex;
        chart.lastVisibleIndex = eIndex;
    }
    checkChartLastVisibleIndex(chart);
    if (chart.onCalculateChartMaxMin) {
        chart.onCalculateChartMaxMin(chart);
    }
    else if (chart.paint.onCalculateChartMaxMin) {
        chart.paint.onCalculateChartMaxMin(chart);
    }
    else {
        calculateChartMaxMin(chart);
    }
}
/*
*右滚
*chart:图表
*step:步长
*/
function scrollRightChart(chart, step) {
    chart.targetOldX = 0;
    chart.targetOldX2 = 0;
    let dataCount = chart.data.length;
    if (chart.showCrossLine) {
        chart.crossStopIndex = chart.crossStopIndex + step;
        if (chart.crossStopIndex <= chart.lastVisibleIndex) {
            step = 0;
        }
        else if (chart.crossStopIndex > dataCount - 1) {
            chart.crossStopIndex = dataCount - 1;
        }
    }
    if (step > 0) {
        let subIndex = chart.lastVisibleIndex - chart.firstVisibleIndex;
        let eIndex = chart.lastVisibleIndex + step;
        if (eIndex > dataCount - 1) {
            eIndex = dataCount - 1;
        }
        let fIndex = eIndex - subIndex;
        chart.firstVisibleIndex = fIndex;
        chart.lastVisibleIndex = eIndex;
    }
    checkChartLastVisibleIndex(chart);
    if (chart.onCalculateChartMaxMin) {
        chart.onCalculateChartMaxMin(chart);
    }
    else if (chart.paint.onCalculateChartMaxMin) {
        chart.paint.onCalculateChartMaxMin(chart);
    }
    else {
        calculateChartMaxMin(chart);
    }
}
/*
*图表的键盘按下事件
*chart:图表
*key:按键
*/
function keyDownChart(chart, key) {
    if (key == 'ArrowUp') {
        zoomOutChart(chart);
    }
    else if (key == 'ArrowDown') {
        zoomInChart(chart);
    }
    else if (key == 'ArrowLeft') {
        scrollLeftChart(chart, 1);
    }
    else if (key == 'ArrowRight') {
        scrollRightChart(chart, 1);
    }
}
/*
* 添加画线
* chart: 图表
* firstTouch:是否第一次触摸
* firstPoint:第一次触摸的坐标
* secondTouch:是否第二次触摸
* secondPoint:第二次触摸的坐标
*/
function addPlotDefault(chart, firstTouch, firstPoint, secondTouch, secondPoint) {
    let mp = firstPoint;
    if (mp.y < getCandleDivHeight(chart)) {
        let touchIndex = getChartIndex(chart, mp);
        if (touchIndex >= chart.firstVisibleIndex && touchIndex <= chart.lastVisibleIndex) {
            if (chart.addingPlotChart == "FiboTimezone") {
                let fIndex = touchIndex;
                let fDate = getChartDateByIndex(chart, fIndex);
                let y = getChartValue(chart, mp);
                let newPlot = new FCPlot;
                if (chart.paint.defaultUIStyle == "light") {
                    newPlot.lineColor = "rgb(0,0,0)";
                    newPlot.pointColor = "rgba(0,0,0,125)";
                }
                else {
                    newPlot.lineColor = "rgb(255,255,255)";
                    newPlot.pointColor = "rgba(255,255,255,125)";
                }
                newPlot.key1 = fDate;
                newPlot.value1 = y;
                newPlot.plotType = chart.addingPlotChart;
                chart.plots.push(newPlot);
                chart.sPlot = selectPlot(chart, mp);
            }
            else if (chart.addingPlotChart == "Triangle" || chart.addingPlotChart == "CircumCycle" || chart.addingPlotChart == "ParalleGram" || chart.addingPlotChart == "AngleLine" || chart.addingPlotChart == "Parallel" || chart.addingPlotChart == "SymmetricTriangle") {
                let eIndex = touchIndex;
                let bIndex = eIndex - 5;
                if (bIndex >= 0) {
                    let fDate = getChartDateByIndex(chart, bIndex);
                    let sDate = getChartDateByIndex(chart, eIndex);
                    let y = getChartValue(chart, mp);
                    let newPlot = new FCPlot;
                    if (chart.paint.defaultUIStyle == "light") {
                        newPlot.lineColor = "rgb(0,0,0)";
                        newPlot.pointColor = "rgba(0,0,0,125)";
                    }
                    else {
                        newPlot.lineColor = "rgb(255,255,255)";
                        newPlot.pointColor = "rgba(255,255,255,125)";
                    }
                    newPlot.key1 = fDate;
                    newPlot.value1 = y;
                    newPlot.key2 = sDate;
                    newPlot.value2 = y;
                    newPlot.key3 = sDate;
                    newPlot.value3 = chart.candleMin + (chart.candleMax - chart.candleMin) / 2;
                    newPlot.plotType = chart.addingPlotChart;
                    chart.plots.push(newPlot);
                    chart.sPlot = selectPlot(chart, mp);
                }
            }
            else {
                let eIndex = touchIndex;
                let bIndex = eIndex - 5;
                if (bIndex >= 0) {
                    let fDate = getChartDateByIndex(chart, bIndex);
                    let sDate = getChartDateByIndex(chart, eIndex);
                    let y = getChartValue(chart, mp);
                    let newPlot = new FCPlot;
                    if (chart.paint.defaultUIStyle == "light") {
                        newPlot.lineColor = "rgb(0,0,0)";
                        newPlot.pointColor = "rgba(0,0,0,125)";
                    }
                    else {
                        newPlot.lineColor = "rgb(255,255,255)";
                        newPlot.pointColor = "rgba(255,255,255,125)";
                    }
                    newPlot.key1 = fDate;
                    newPlot.value1 = y;
                    newPlot.key2 = sDate;
                    newPlot.value2 = y;
                    newPlot.plotType = chart.addingPlotChart;
                    chart.plots.push(newPlot);
                    chart.sPlot = selectPlot(chart, mp);
                }
            }
        }
    }
}
/*
* 图表的鼠标移动方法
* chart: 图表
* firstTouch:是否第一次触摸
* firstPoint:第一次触摸的坐标
* secondTouch:是否第二次触摸
* secondPoint:第二次触摸的坐标
*/
function touchMoveChart(chart, firstTouch, firstPoint, secondTouch, secondPoint) {
    if (!chart.data || chart.data.length == 0) {
        return;
    }
    let mp = firstPoint;
    chart.crossStopIndex = getChartIndex(chart, mp);
    chart.touchPosition = mp;
    chart.targetOldX = 0;
    chart.targetOldX2 = 0;
    if (firstTouch && chart.sPlot) {
        let newIndex = getChartIndex(chart, mp);
        if (newIndex >= 0 && newIndex < chart.data.length) {
            let newDate = getChartDateByIndex(chart, newIndex);
            let newValue = getCandleDivValue(chart, mp);
            if (chart.selectPlotPoint == 0) {
                chart.sPlot.key1 = newDate;
                chart.sPlot.value1 = newValue;
            }
            else if (chart.selectPlotPoint == 1) {
                chart.sPlot.key2 = newDate;
                chart.sPlot.value2 = newValue;
            }
            else if (chart.selectPlotPoint == 2) {
                chart.sPlot.key3 = newDate;
                chart.sPlot.value3 = newValue;
            }
            else if (chart.startMovePlot) {
                let bValue = getCandleDivValue(chart, chart.touchDownPointChart);
                let bIndex = getChartIndex(chart, chart.touchDownPointChart);
                if (chart.sPlot.key1) {
                    chart.sPlot.value1 = chart.sPlot.startValue1 + (newValue - bValue);
                    let startIndex1 = getChartIndexByDate(chart, chart.sPlot.startKey1);
                    let newIndex1 = startIndex1 + (newIndex - bIndex);
                    if (newIndex1 < 0) {
                        newIndex1 = 0;
                    }
                    else if (newIndex1 > chart.data.length - 1) {
                        newIndex1 = chart.data.length - 1;
                    }
                    chart.sPlot.key1 = getChartDateByIndex(chart, newIndex1);
                }
                if (chart.sPlot.key2) {
                    chart.sPlot.value2 = chart.sPlot.startValue2 + (newValue - bValue);
                    let startIndex2 = getChartIndexByDate(chart, chart.sPlot.startKey2);
                    let newIndex2 = startIndex2 + (newIndex - bIndex);
                    if (newIndex2 < 0) {
                        newIndex2 = 0;
                    }
                    else if (newIndex2 > chart.data.length - 1) {
                        newIndex2 = chart.data.length - 1;
                    }
                    chart.sPlot.key2 = getChartDateByIndex(chart, newIndex2);
                }
                if (chart.sPlot.key3) {
                    chart.sPlot.value3 = chart.sPlot.startValue3 + (newValue - bValue);
                    let startIndex3 = getChartIndexByDate(chart, chart.sPlot.startKey3);
                    let newIndex3 = startIndex3 + (newIndex - bIndex);
                    if (newIndex3 < 0) {
                        newIndex3 = 0;
                    }
                    else if (newIndex3 > chart.data.length - 1) {
                        newIndex3 = chart.data.length - 1;
                    }
                    chart.sPlot.key3 = getChartDateByIndex(chart, newIndex3);
                }
            }
        }
        return;
    }
    if (firstTouch && secondTouch) {
        if (firstPoint.x > secondPoint.x) {
            chart.firstTouchPointCacheChart = secondPoint;
            chart.secondTouchPointCacheChart = firstPoint;
        }
        else {
            chart.firstTouchPointCacheChart = firstPoint;
            chart.secondTouchPointCacheChart = secondPoint;
        }
        if (chart.firstTouchIndexCacheChart == -1 || chart.secondTouchIndexCacheChart == -1) {
            chart.firstTouchIndexCacheChart = getChartIndex(chart, chart.firstTouchPointCacheChart);
            chart.secondTouchIndexCacheChart = getChartIndex(chart, chart.secondTouchPointCacheChart);
            chart.firstIndexCacheChart = chart.firstVisibleIndex;
            chart.lastIndexCacheChart = chart.lastVisibleIndex;
        }
    }
    else if (firstTouch) {
        chart.secondTouchIndexCacheChart = -1;
        if (chart.firstTouchIndexCacheChart == -1) {
            chart.firstTouchPointCacheChart = firstPoint;
            chart.firstTouchIndexCacheChart = getChartIndex(chart, chart.firstTouchPointCacheChart);
            chart.firstIndexCacheChart = chart.firstVisibleIndex;
            chart.lastIndexCacheChart = chart.lastVisibleIndex;
            chart.firstPaddingTop = chart.candlePaddingTop;
            chart.firtstPaddingBottom = chart.candlePaddingBottom;
        }
    }
    if (firstTouch && secondTouch) {
        if (chart.firstTouchIndexCacheChart != -1 && chart.secondTouchIndexCacheChart != -1) {
            let fPoint = firstPoint;
            let sPoint = secondPoint;
            if (firstPoint.x > secondPoint.x) {
                fPoint = secondPoint;
                sPoint = firstPoint;
                ;
            }
            let subX = Math.abs(sPoint.x - fPoint.x);
            let subIndex = Math.abs(chart.secondTouchIndexCacheChart - chart.firstTouchIndexCacheChart);
            if (subX > 0 && subIndex > 0) {
                let newScalePixel = subX / subIndex;
                if (newScalePixel >= 3) {
                    let intScalePixel = Math.floor(newScalePixel);
                    newScalePixel = intScalePixel;
                }
                if (newScalePixel != chart.hScalePixel) {
                    let newFirstIndex = chart.firstTouchIndexCacheChart;
                    let thisX = fPoint.x;
                    thisX -= newScalePixel;
                    while (thisX > chart.leftVScaleWidth + newScalePixel) {
                        newFirstIndex--;
                        if (newFirstIndex < 0) {
                            newFirstIndex = 0;
                            break;
                        }
                        thisX -= newScalePixel;
                    }
                    thisX = sPoint.x;
                    let newSecondIndex = chart.secondTouchIndexCacheChart;
                    thisX += newScalePixel;
                    while (thisX < chart.size.cx - chart.rightVScaleWidth - newScalePixel) {
                        newSecondIndex++;
                        if (newSecondIndex > chart.data.length - 1) {
                            newSecondIndex = chart.data.length - 1;
                            break;
                        }
                        thisX += newScalePixel;
                    }
                    setChartVisibleIndex(chart, newFirstIndex, newSecondIndex);
                    let maxVisibleRecord = getChartMaxVisibleCount(chart, chart.hScalePixel, getChartWorkAreaWidth(chart));
                    while (maxVisibleRecord < chart.lastVisibleIndex - chart.firstVisibleIndex + 1
                        && chart.lastVisibleIndex > chart.firstVisibleIndex) {
                        chart.lastVisibleIndex--;
                    }
                    checkChartLastVisibleIndex(chart);
                    resetChartVisibleRecord(chart);
                    if (chart.onCalculateChartMaxMin) {
                        chart.onCalculateChartMaxMin(chart);
                    }
                    else if (chart.paint.onCalculateChartMaxMin) {
                        chart.paint.onCalculateChartMaxMin(chart);
                    }
                    else {
                        calculateChartMaxMin(chart);
                    }
                }
            }
        }
    }
    else if (firstTouch) {
        if (!chart.autoFillHScale) {
            let subIndex = Math.floor((chart.firstTouchPointCacheChart.x - firstPoint.x) / chart.hScalePixel);
            if (chart.allowDragChartDiv) {
                chart.candlePaddingTop = chart.firstPaddingTop - (chart.firstTouchPointCacheChart.y - firstPoint.y);
                chart.candlePaddingBottom = chart.firtstPaddingBottom + (chart.firstTouchPointCacheChart.y - firstPoint.y);
            }
            let fIndex = chart.firstIndexCacheChart + subIndex;
            let lIndex = chart.lastIndexCacheChart + subIndex;
            if (fIndex > chart.data.length - 1) {
                fIndex = chart.data.length - 1;
                lIndex = chart.data.length - 1;
            }
            chart.firstVisibleIndex = fIndex;
            chart.lastVisibleIndex = lIndex;
            checkChartLastVisibleIndex(chart);
            if (chart.onCalculateChartMaxMin) {
                chart.onCalculateChartMaxMin(chart);
            }
            else if (chart.paint.onCalculateChartMaxMin) {
                chart.paint.onCalculateChartMaxMin(chart);
            }
            else {
                calculateChartMaxMin(chart);
            }
        }
    }
}
/*
* 绘制画线工具
* chart:图表
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawChartPlot(chart, paint, clipRect) {
    paint.save();
    let divHeight = getCandleDivHeight(chart);
    paint.setClip(chart.leftVScaleWidth, 0, chart.size.cx - chart.rightVScaleWidth, divHeight);
    for (let i = 0; i < chart.plots.length; i++) {
        let plot = chart.plots[i];
        let index1 = 0, index2 = 0, index3 = 0;
        let mpx1 = 0, mpy1 = 0, mpx2 = 0, mpy2 = 0, mpx3 = 0, mpy3 = 0;
        if (plot.plotType == "LRLine" || plot.plotType == "LRChannel" || plot.plotType == "LRBand") {
            let list = new Array();
            index1 = getChartIndexByDate(chart, plot.key1);
            index2 = getChartIndexByDate(chart, plot.key2);
            let minIndex = Math.min(index1, index2);
            let maxIndex = Math.max(index1, index2);
            for (let j = minIndex; j <= maxIndex; j++) {
                list.push(chart.data[j].close);
            }
            linearRegressionEquation(chart, list);
            plot.value1 = chart.bChart;
            plot.value2 = chart.kChart * (maxIndex - minIndex + 1) + chart.bChart;
        }
        else if (plot.plotType == "BoxLine" || plot.plotType == "TironeLevels" || plot.plotType == "QuadrantLines") {
            getCandleRange(chart, plot);
            let nHigh = chart.nHighChart, nLow = chart.nLowChart;
            index1 = getChartIndexByDate(chart, plot.key1);
            index2 = getChartIndexByDate(chart, plot.key2);
            plot.key1 = getChartDateByIndex(chart, Math.min(index1, index2));
            plot.key2 = getChartDateByIndex(chart, Math.max(index1, index2));
            plot.value1 = nHigh;
            plot.value2 = nLow;
        }
        if (plot.key1) {
            index1 = getChartIndexByDate(chart, plot.key1);
            mpx1 = getChartX(chart, index1);
            mpy1 = getChartY(chart, 0, plot.value1);
            if (chart.sPlot == plot) {
                paint.fillEllipse(plot.pointColor, mpx1 - chart.plotPointSizeChart, mpy1 - chart.plotPointSizeChart, mpx1 + chart.plotPointSizeChart, mpy1 + chart.plotPointSizeChart);
            }
        }
        if (plot.key2) {
            index2 = getChartIndexByDate(chart, plot.key2);
            mpx2 = getChartX(chart, index2);
            mpy2 = getChartY(chart, 0, plot.value2);
            if (chart.sPlot == plot) {
                paint.fillEllipse(plot.pointColor, mpx2 - chart.plotPointSizeChart, mpy2 - chart.plotPointSizeChart, mpx2 + chart.plotPointSizeChart, mpy2 + chart.plotPointSizeChart);
            }
        }
        if (plot.key3) {
            index3 = getChartIndexByDate(chart, plot.key3);
            mpx3 = getChartX(chart, index3);
            mpy3 = getChartY(chart, 0, plot.value3);
            if (chart.sPlot == plot) {
                paint.fillEllipse(plot.pointColor, mpx3 - chart.plotPointSizeChart, mpy3 - chart.plotPointSizeChart, mpx3 + chart.plotPointSizeChart, mpy3 + chart.plotPointSizeChart);
            }
        }
        if (plot.plotType == "Line") {
            lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0);
            if (mpx2 == mpx1) {
                paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, 0, mpx1, divHeight);
            }
            else {
                let newX1 = chart.leftVScaleWidth;
                let newY1 = newX1 * chart.kChart + chart.bChart;
                let newX2 = chart.size.cx - chart.rightVScaleWidth;
                let newY2 = newX2 * chart.kChart + chart.bChart;
                paint.drawLine(plot.lineColor, plot.lineWidth, null, newX1, newY1, newX2, newY2);
            }
        }
        else if (plot.plotType == "ArrowSegment") {
            let ARROW_Size = 24;
            let slopy, cosy, siny;
            slopy = Math.atan2(mpy1 - mpy2, mpx1 - mpx2);
            cosy = Math.cos(slopy);
            siny = Math.sin(slopy);
            let ptPoint = new FCPoint(0, 0);
            ptPoint.x = mpx2;
            ptPoint.y = mpy2;
            let pts = new Array();
            pts.push(new FCPoint(0, 0));
            pts.push(new FCPoint(0, 0));
            pts.push(new FCPoint(0, 0));
            pts[0] = ptPoint;
            pts[1].x = ptPoint.x + (ARROW_Size * cosy - (ARROW_Size / 2.0 * siny) + 0.5);
            pts[1].y = ptPoint.y + (ARROW_Size * siny + (ARROW_Size / 2.0 * cosy) + 0.5);
            pts[2].x = ptPoint.x + (ARROW_Size * cosy + ARROW_Size / 2.0 * siny + 0.5);
            pts[2].y = ptPoint.y - (ARROW_Size / 2.0 * cosy - ARROW_Size * siny + 0.5);
            ARROW_Size = 20;
            let ptPoint2 = new FCPoint(0, 0);
            ptPoint2.x = mpx2;
            ptPoint2.y = mpy2;
            let pts2 = new Array();
            pts2.push(new FCPoint(0, 0));
            pts2.push(new FCPoint(0, 0));
            pts2.push(new FCPoint(0, 0));
            pts2[0] = ptPoint2;
            pts2[1].x = ptPoint2.x + (ARROW_Size * cosy - (ARROW_Size / 2.0 * siny) + 0.5);
            pts2[1].y = ptPoint2.y + (ARROW_Size * siny + (ARROW_Size / 2.0 * cosy) + 0.5);
            pts2[2].x = ptPoint2.x + (ARROW_Size * cosy + ARROW_Size / 2.0 * siny + 0.5);
            pts2[2].y = ptPoint2.y - (ARROW_Size / 2.0 * cosy - ARROW_Size * siny + 0.5);
            lineXY(chart, pts2[1].x, pts2[1].y, pts2[2].x, pts2[2].y, 0, 0);
            let newX1 = 0, newY1 = 0, newX2 = 0, newY2 = 0;
            if (pts2[1].x > pts2[2].x) {
                newX1 = pts2[2].x + (pts2[1].x - pts2[2].x) / 3;
                newX2 = pts2[2].x + (pts2[1].x - pts2[2].x) * 2 / 3;
            }
            else {
                newX1 = pts2[1].x + (pts2[2].x - pts2[1].x) / 3;
                newX2 = pts2[1].x + (pts2[2].x - pts2[1].x) * 2 / 3;
            }
            if (chart.kChart == 0 && chart.bChart == 0) {
                if (pts2[1].y > pts2[2].y) {
                    newY1 = pts2[2].y + (pts2[1].y - pts2[2].y) / 3;
                    newY2 = pts2[2].y + (pts2[1].y - pts2[2].y) * 2 / 3;
                }
                else {
                    newY1 = pts2[1].y + (pts2[2].y - pts2[1].y) / 3;
                    newY2 = pts2[1].y + (pts2[2].y - pts2[1].y) * 2 / 3;
                }
            }
            else {
                newY1 = (chart.kChart * newX1) + chart.bChart;
                newY2 = (chart.kChart * newX2) + chart.bChart;
            }
            pts2[1].x = newX1;
            pts2[1].y = newY1;
            pts2[2].x = newX2;
            pts2[2].y = newY2;
            let drawPoints = new Array();
            drawPoints.push(new FCPoint(0, 0));
            drawPoints.push(new FCPoint(0, 0));
            drawPoints.push(new FCPoint(0, 0));
            drawPoints.push(new FCPoint(0, 0));
            drawPoints.push(new FCPoint(0, 0));
            drawPoints.push(new FCPoint(0, 0));
            drawPoints[0].x = ptPoint.x;
            drawPoints[0].y = ptPoint.y;
            drawPoints[1].x = pts[1].x;
            drawPoints[1].y = pts[1].y;
            if (mpy1 >= mpy2) {
                drawPoints[2].x = pts2[1].x;
                drawPoints[2].y = pts2[1].y;
            }
            else {
                drawPoints[2].x = pts2[2].x;
                drawPoints[2].y = pts2[2].y;
            }
            drawPoints[3].x = mpx1;
            drawPoints[3].y = mpy1;
            if (mpy1 >= mpy2) {
                drawPoints[4].x = pts2[2].x;
                drawPoints[4].y = pts2[2].y;
            }
            else {
                drawPoints[4].x = pts2[1].x;
                drawPoints[4].y = pts2[1].y;
            }
            drawPoints[5].x = pts[2].x;
            drawPoints[5].y = pts[2].y;
            paint.beginPath();
            for (let j = 0; j < 6; j++) {
                if (j > 0) {
                    paint.addLine(drawPoints[j - 1].x, drawPoints[j - 1].y, drawPoints[j].x, drawPoints[j].y);
                }
            }
            paint.fillPath(plot.lineColor);
            paint.closePath();
        }
        else if (plot.plotType == "AngleLine") {
            lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0);
            if (mpx2 == mpx1) {
                paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, 0, mpx1, divHeight);
            }
            else {
                let newX1 = chart.leftVScaleWidth;
                let newY1 = newX1 * chart.kChart + chart.bChart;
                let newX2 = chart.size.cx - chart.rightVScaleWidth;
                let newY2 = newX2 * chart.kChart + chart.bChart;
                paint.drawLine(plot.lineColor, plot.lineWidth, null, newX1, newY1, newX2, newY2);
            }
            lineXY(chart, mpx1, mpy1, mpx3, mpy3, 0, 0);
            if (mpx3 == mpx1) {
                paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, 0, mpx1, divHeight);
            }
            else {
                let newX1 = chart.leftVScaleWidth;
                let newY1 = newX1 * chart.kChart + chart.bChart;
                let newX2 = chart.size.cx - chart.rightVScaleWidth;
                let newY2 = newX2 * chart.kChart + chart.bChart;
                paint.drawLine(plot.lineColor, plot.lineWidth, null, newX1, newY1, newX2, newY2);
            }
        }
        else if (plot.plotType == "Parallel") {
            lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0);
            if (mpx2 == mpx1) {
                paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, 0, mpx1, divHeight);
            }
            else {
                let newX1 = chart.leftVScaleWidth;
                let newY1 = newX1 * chart.kChart + chart.bChart;
                let newX2 = chart.size.cx - chart.rightVScaleWidth;
                let newY2 = newX2 * chart.kChart + chart.bChart;
                paint.drawLine(plot.lineColor, plot.lineWidth, null, newX1, newY1, newX2, newY2);
            }
            let newB = mpy3 - chart.kChart * mpx3;
            if (mpx2 == mpx1) {
                paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx3, 0, mpx3, divHeight);
            }
            else {
                let newX1 = chart.leftVScaleWidth;
                let newY1 = newX1 * chart.kChart + newB;
                let newX2 = chart.size.cx - chart.rightVScaleWidth;
                let newY2 = newX2 * chart.kChart + newB;
                paint.drawLine(plot.lineColor, plot.lineWidth, null, newX1, newY1, newX2, newY2);
            }
        }
        else if (plot.plotType == "Percent") {
            let list = getPercentParams(mpy1, mpy2);
            let texts = new Array();
            texts.push("0%");
            texts.push("25%");
            texts.push("50%");
            texts.push("75%");
            texts.push("100%");
            for (let j = 0; j < list.length; j++) {
                paint.drawLine(plot.lineColor, plot.lineWidth, null, chart.leftVScaleWidth, list[j], chart.size.cx - chart.rightVScaleWidth, list[j]);
                let tSize = paint.textSize(texts[j], chart.font);
                paint.drawText(texts[j], chart.textColor, chart.font, chart.leftVScaleWidth + 5, list[j] - tSize.cy - 2);
            }
        }
        else if (plot.plotType == "FiboTimezone") {
            let fValue = 1;
            let aIndex = index1;
            let pos = 1;
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, 0, mpx1, divHeight);
            let tSize = paint.textSize("1", chart.font);
            paint.drawText("1", chart.textColor, chart.font, mpx1, divHeight - tSize.cy);
            while (aIndex + fValue <= chart.lastVisibleIndex) {
                fValue = fibonacciValue(pos);
                let newIndex = aIndex + fValue;
                let newX = getChartX(chart, newIndex);
                paint.drawLine(plot.lineColor, plot.lineWidth, null, newX, 0, newX, divHeight);
                let tSize2 = paint.textSize(fValue.toString(), chart.font);
                paint.drawText(fValue.toString(), chart.textColor, chart.font, newX, divHeight - tSize2.cy);
                pos++;
            }
        }
        else if (plot.plotType == "SpeedResist") {
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, mpy1, mpx2, mpy2);
            if (mpx1 != mpx2 && mpy1 != mpy2) {
                let firstP = new FCPoint(mpx2, mpy2 - (mpy2 - mpy1) / 3);
                let secondP = new FCPoint(mpx2, mpy2 - (mpy2 - mpy1) * 2 / 3);
                let startP = new FCPoint(mpx1, mpy1);
                let fK = 0, fB = 0, sK = 0, sB = 0;
                lineXY(chart, startP.x, startP.y, firstP.x, firstP.y, 0, 0);
                fK = chart.kChart;
                fB = chart.bChart;
                lineXY(chart, startP.x, startP.y, secondP.x, secondP.y, 0, 0);
                sK = chart.kChart;
                sB = chart.bChart;
                let newYF = 0, newYS = 0;
                let newX = 0;
                if (mpx2 > mpx1) {
                    newYF = fK * (chart.size.cx - chart.rightVScaleWidth) + fB;
                    newYS = sK * (chart.size.cx - chart.rightVScaleWidth) + sB;
                    newX = (chart.size.cx - chart.rightVScaleWidth);
                }
                else {
                    newYF = fB;
                    newYS = sB;
                    newX = chart.leftVScaleWidth;
                }
                paint.drawLine(plot.lineColor, plot.lineWidth, null, startP.x, startP.y, newX, newYF);
                paint.drawLine(plot.lineColor, plot.lineWidth, null, startP.x, startP.y, newX, newYS);
            }
        }
        else if (plot.plotType == "FiboFanline") {
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, mpy1, mpx2, mpy2);
            if (mpx1 != mpx2 && mpy1 != mpy2) {
                let firstP = new FCPoint(mpx2, mpy2 - (mpy2 - mpy1) * 0.382);
                let secondP = new FCPoint(mpx2, mpy2 - (mpy2 - mpy1) * 0.5);
                let thirdP = new FCPoint(mpx2, mpy2 - (mpy2 - mpy1) * 0.618);
                let startP = new FCPoint(mpx1, mpy1);
                let listP = new Array();
                listP.push(firstP);
                listP.push(secondP);
                listP.push(thirdP);
                let listSize = listP.length;
                for (let j = 0; j < listSize; j++) {
                    //获取直线参数
                    lineXY(chart, startP.x, startP.y, listP[j].x, listP[j].y, 0, 0);
                    let newX = 0;
                    let newY = 0;
                    if (mpx2 > mpx1) {
                        newY = chart.kChart * (chart.size.cx - chart.rightVScaleWidth) + chart.bChart;
                        newX = (chart.size.cx - chart.rightVScaleWidth);
                    }
                    else {
                        newY = chart.bChart;
                        newX = chart.leftVScaleWidth;
                    }
                    paint.drawLine(plot.lineColor, plot.lineWidth, null, startP.x, startP.y, newX, newY);
                }
            }
        }
        else if (plot.plotType == "LRLine") {
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, mpy1, mpx2, mpy2);
        }
        else if (plot.plotType == "LRBand") {
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, mpy1, mpx2, mpy2);
            getLRBandRange(chart, plot, chart.kChart, chart.bChart);
            mpy1 = getChartY(chart, 0, plot.value1 + chart.upSubValue);
            mpy2 = getChartY(chart, 0, plot.value2 + chart.upSubValue);
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, mpy1, mpx2, mpy2);
            mpy1 = getChartY(chart, 0, plot.value1 - chart.downSubValue);
            mpy2 = getChartY(chart, 0, plot.value2 - chart.downSubValue);
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, mpy1, mpx2, mpy2);
        }
        else if (plot.plotType == "LRChannel") {
            getLRBandRange(chart, plot, chart.kChart, chart.bChart);
            lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0);
            let rightX = chart.size.cx - chart.rightVScaleWidth;
            let rightY = rightX * chart.kChart + chart.bChart;
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, mpy1, rightX, rightY);
            mpy1 = getChartY(chart, 0, plot.value1 + chart.upSubValue);
            mpy2 = getChartY(chart, 0, plot.value2 + chart.upSubValue);
            lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0);
            rightY = rightX * chart.kChart + chart.bChart;
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, mpy1, rightX, rightY);
            mpy1 = getChartY(chart, 0, plot.value1 - chart.downSubValue);
            mpy2 = getChartY(chart, 0, plot.value2 - chart.downSubValue);
            lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0);
            rightY = rightX * chart.kChart + chart.bChart;
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, mpy1, rightX, rightY);
        }
        else if (plot.plotType == "Segment") {
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, mpy1, mpx2, mpy2);
        }
        else if (plot.plotType == "Ray") {
            lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0);
            if (chart.kChart != 0 || chart.bChart != 0) {
                let leftX = chart.leftVScaleWidth;
                let leftY = leftX * chart.kChart + chart.bChart;
                let rightX = chart.size.cx - chart.rightVScaleWidth;
                let rightY = rightX * chart.kChart + chart.bChart;
                if (mpx1 >= mpx2) {
                    paint.drawLine(plot.lineColor, plot.lineWidth, null, leftX, leftY, mpx1, mpy1);
                }
                else {
                    paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, mpy1, rightX, rightY);
                }
            }
            //垂直时
            else {
                if (mpy1 >= mpy2) {
                    paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, mpy1, mpx1, 0);
                }
                else {
                    paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, mpy1, mpx1, divHeight);
                }
            }
        }
        else if (plot.plotType == "Triangle") {
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, mpy1, mpx2, mpy2);
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx2, mpy2, mpx3, mpy3);
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, mpy1, mpx3, mpy3);
        }
        else if (plot.plotType == "SymmetricTriangle") {
            if (mpx2 != mpx1) {
                let a = (mpy2 - mpy1) / (mpx2 - mpx1);
                let b = mpy1 - a * mpx1;
                let c = -a;
                let d = mpy3 - c * mpx3;
                let leftX = chart.leftVScaleWidth;
                let leftY = leftX * a + b;
                let rightX = chart.size.cx - chart.rightVScaleWidth;
                let rightY = rightX * a + b;
                paint.drawLine(plot.lineColor, plot.lineWidth, null, leftX, leftY, rightX, rightY);
                leftY = leftX * c + d;
                rightY = rightX * c + d;
                paint.drawLine(plot.lineColor, plot.lineWidth, null, leftX, leftY, rightX, rightY);
            }
            else {
                paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, 0, mpx1, divHeight);
                paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx3, 0, mpx3, divHeight);
            }
        }
        else if (plot.plotType == "Rect") {
            let sX1 = Math.min(mpx1, mpx2);
            let sY1 = Math.min(mpy1, mpy2);
            let sX2 = Math.max(mpx1, mpx2);
            let sY2 = Math.max(mpy1, mpy2);
            paint.drawRect(plot.lineColor, plot.lineWidth, null, sX1, sY1, sX2, sY2);
        }
        else if (plot.plotType == "Cycle") {
            let r = Math.sqrt(Math.abs((mpx2 - mpx1) * (mpx2 - mpx1) + (mpy2 - mpy1) * (mpy2 - mpy1)));
            paint.drawEllipse(plot.lineColor, plot.lineWidth, null, mpx1 - r, mpy1 - r, mpx1 + r, mpy1 + r);
        }
        else if (plot.plotType == "CircumCycle") {
            ellipseOR(chart, mpx1, mpy1, mpx2, mpy2, mpx3, mpy3);
            paint.drawEllipse(plot.lineColor, plot.lineWidth, null, chart.oXChart - chart.rChart, chart.oYChart - chart.rChart, chart.oXChart + chart.rChart, chart.oYChart + chart.rChart);
        }
        else if (plot.plotType == "Ellipse") {
            let x1 = 0, y1 = 0, x2 = 0, y2 = 0;
            if (mpx1 <= mpx2) {
                x1 = mpx2;
                y1 = mpy2;
                x2 = mpx1;
                y2 = mpy1;
            }
            else {
                x1 = mpx1;
                y1 = mpy1;
                x2 = mpx2;
                y2 = mpy2;
            }
            let x = x1 - (x1 - x2);
            let y = 0;
            let width = (x1 - x2) * 2;
            let height = 0;
            if (y1 >= y2) {
                height = (y1 - y2) * 2;
            }
            else {
                height = (y2 - y1) * 2;
            }
            y = y2 - height / 2;
            paint.drawEllipse(plot.lineColor, plot.lineWidth, null, x, y, x + width, y + height);
        }
        else if (plot.plotType == "ParalleGram") {
            parallelogram(chart, mpx1, mpy1, mpx2, mpy2, mpx3, mpy3);
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx1, mpy1, mpx2, mpy2);
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx2, mpy2, mpx3, mpy3);
            paint.drawLine(plot.lineColor, plot.lineWidth, null, mpx3, mpy3, chart.x4Chart, chart.y4Chart);
            paint.drawLine(plot.lineColor, plot.lineWidth, null, chart.x4Chart, chart.y4Chart, mpx1, mpy1);
        }
        else if (plot.plotType == "BoxLine") {
            let sX1 = Math.min(mpx1, mpx2);
            let sY1 = Math.min(mpy1, mpy2);
            let sX2 = Math.max(mpx1, mpx2);
            let sY2 = Math.max(mpy1, mpy2);
            paint.drawRect(plot.lineColor, plot.lineWidth, null, sX1, sY1, sX2, sY2);
            let bSize = paint.textSize("COUNT:" + Math.abs(index2 - index1) + 1, chart.font);
            paint.drawText("COUNT:" + Math.abs(index2 - index1) + 1, chart.textColor, chart.font, sX1 + 2, sY1 + 2);
            let closeList = new Array();
            for (let j = index1; j <= index2; j++) {
                closeList.push(chart.data[j].close);
            }
            let avgClose = avgValue(closeList);
            let closeY = getChartY(chart, 0, avgClose);
            paint.drawLine(plot.lineColor, plot.lineWidth, [5, 5], sX1, closeY, sX2, closeY);
            let drawAvg = "AVG:" + avgClose.toFixed(chart.candleDigit);
            let tSize = paint.textSize(drawAvg, chart.font);
            paint.drawText(drawAvg, chart.textColor, chart.font, sX1 + 2, closeY - tSize.cy - 2);
        }
        else if (plot.plotType == "TironeLevels") {
            let sX1 = Math.min(mpx1, mpx2);
            let sY1 = Math.min(mpy1, mpy2);
            let sX2 = Math.max(mpx1, mpx2);
            let sY2 = Math.max(mpy1, mpy2);
            paint.drawLine(plot.lineColor, plot.lineWidth, null, sX1, sY1, sX2, sY1);
            paint.drawLine(plot.lineColor, plot.lineWidth, null, sX1, sY2, sX2, sY2);
            paint.drawLine(plot.lineColor, plot.lineWidth, [5, 5], sX1 + (sX2 - sX1) / 2, sY1, sX1 + (sX2 - sX1) / 2, sY2);
            let t1 = chart.nHighChart, t2 = chart.nHighChart - (chart.nHighChart - chart.nLowChart) / 3, t3 = chart.nHighChart - (chart.nHighChart - chart.nLowChart) / 2, t4 = chart.nHighChart - 2 * (chart.nHighChart - chart.nLowChart) / 3, t5 = chart.nLowChart;
            let tList = new Array();
            tList.push(t2);
            tList.push(t3);
            tList.push(t4);
            for (let j = 0; j < tList.length; j++) {
                let y = getChartY(chart, 0, tList[j]);
                //画直线
                paint.drawLine(plot.lineColor, plot.lineWidth, [5, 5], chart.leftVScaleWidth, y, chart.size.cx - chart.rightVScaleWidth, y);
                let str = tList[j].toFixed(chart.candleDigit);
                let tSize = paint.textSize(str, chart.font);
                paint.drawText(str, chart.textColor, chart.font, chart.leftVScaleWidth + 2, y - tSize.cy - 2);
            }
        }
        else if (plot.plotType == "QuadrantLines") {
            let sX1 = Math.min(mpx1, mpx2);
            let sY1 = Math.min(mpy1, mpy2);
            let sX2 = Math.max(mpx1, mpx2);
            let sY2 = Math.max(mpy1, mpy2);
            paint.drawLine(plot.lineColor, plot.lineWidth, null, sX1, sY1, sX2, sY1);
            paint.drawLine(plot.lineColor, plot.lineWidth, null, sX1, sY2, sX2, sY2);
            let t1 = chart.nHighChart, t2 = chart.nHighChart - (chart.nHighChart - chart.nLowChart) / 4, t3 = chart.nHighChart - (chart.nHighChart - chart.nLowChart) / 2, t4 = chart.nHighChart - 3 * (chart.nHighChart - chart.nLowChart) / 4, t5 = chart.nLowChart;
            let tList = new Array();
            tList.push(t2);
            tList.push(t3);
            tList.push(t4);
            for (let j = 0; j < tList.length; j++) {
                let y = getChartY(chart, 0, tList[j]);
                //画直线
                paint.drawLine(plot.lineColor, plot.lineWidth, null, sX1, y, sX2, y);
            }
        }
        else if (plot.plotType == "GoldenRatio") {
            let sX1 = Math.min(mpx1, mpx2);
            let sY1 = Math.min(mpy1, mpy2);
            let sX2 = Math.max(mpx1, mpx2);
            let sY2 = Math.max(mpy1, mpy2);
            let ranges = new Array();
            ranges.push(0);
            ranges.push(0.236);
            ranges.push(0.382);
            ranges.push(0.5);
            ranges.push(0.618);
            ranges.push(0.809);
            ranges.push(1);
            ranges.push(1.382);
            ranges.push(1.618);
            ranges.push(2);
            ranges.push(2.382);
            ranges.push(2.618);
            let minValue = Math.min(plot.value1, plot.value2);
            let maxValue = Math.max(plot.value1, plot.value2);
            for (let j = 0; j < ranges.length; j++) {
                let newY = sY1 <= sY2 ? sY1 + (sY2 - sY1) * ranges[j] : sY2 + (sY1 - sY2) * (1 - ranges[j]);
                paint.drawLine(plot.lineColor, plot.lineWidth, null, chart.leftVScaleWidth, newY, chart.size.cx - chart.rightVScaleWidth, newY);
                let newPoint = new FCPoint(0, newY);
                let value = getCandleDivValue(chart, newPoint);
                let str = value.toFixed(chart.candleDigit);
                let tSize = paint.textSize(str, chart.font);
                paint.drawText(str, chart.textColor, chart.font, chart.leftVScaleWidth + 2, newY - tSize.cy - 2);
            }
        }
    }
    paint.restore();
}
/*
* 选中直线
* chart: 图表
* mp:坐标
*/
function selectPlot(chart, mp) {
    let sPlot = null;
    chart.startMovePlot = false;
    chart.selectPlotPoint = -1;
    for (let i = 0; i < chart.plots.length; i++) {
        let plot = chart.plots[i];
        let index1 = 0, index2 = 0, index3 = 0;
        let mpx1 = 0, mpy1 = 0, mpx2 = 0, mpy2 = 0, mpx3 = 0, mpy3 = 0;
        //检查关键点
        if (plot.key1) {
            index1 = getChartIndexByDate(chart, plot.key1);
            mpx1 = getChartX(chart, index1);
            mpy1 = getChartY(chart, 0, plot.value1);
            if (mp.x >= mpx1 - chart.plotPointSizeChart && mp.x <= mpx1 + chart.plotPointSizeChart && mp.y >= mpy1 - chart.plotPointSizeChart && mp.y <= mpy1 + chart.plotPointSizeChart) {
                sPlot = plot;
                chart.selectPlotPoint = 0;
                break;
            }
        }
        if (plot.key2) {
            index2 = getChartIndexByDate(chart, plot.key2);
            mpx2 = getChartX(chart, index2);
            mpy2 = getChartY(chart, 0, plot.value2);
            if (mp.x >= mpx2 - chart.plotPointSizeChart && mp.x <= mpx2 + chart.plotPointSizeChart && mp.y >= mpy2 - chart.plotPointSizeChart && mp.y <= mpy2 + chart.plotPointSizeChart) {
                sPlot = plot;
                chart.selectPlotPoint = 1;
                break;
            }
        }
        if (plot.key3) {
            index3 = getChartIndexByDate(chart, plot.key3);
            mpx3 = getChartX(chart, index3);
            mpy3 = getChartY(chart, 0, plot.value3);
            if (mp.x >= mpx3 - chart.plotPointSizeChart && mp.x <= mpx3 + chart.plotPointSizeChart && mp.y >= mpy3 - chart.plotPointSizeChart && mp.y <= mpy3 + chart.plotPointSizeChart) {
                sPlot = plot;
                chart.selectPlotPoint = 2;
                break;
            }
        }
        //判断其余部分的选中
        if (chart.selectPlotPoint == -1) {
            if (plot.plotType == "Line") {
                chart.startMovePlot = selectLine(chart, mp, mpx1, mpy1, mpx2, mpy2);
            }
            else if (plot.plotType == "ArrowSegment") {
                chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2);
            }
            else if (plot.plotType == "AngleLine") {
                chart.startMovePlot = selectLine(chart, mp, mpx1, mpy1, mpx2, mpy2);
                if (!chart.startMovePlot) {
                    chart.startMovePlot = selectLine(chart, mp, mpx1, mpy1, mpx3, mpy3);
                }
            }
            else if (plot.plotType == "Parallel") {
                chart.startMovePlot = selectLine(chart, mp, mpx1, mpy1, mpx2, mpy2);
                if (!chart.startMovePlot) {
                    lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0);
                    let newB = mpy3 - chart.kChart * mpx3;
                    if (mpx2 == mpx1) {
                        if (mp.x >= mpx3 - chart.plotPointSizeChart && mp.x <= mpx3 + chart.plotPointSizeChart) {
                            chart.startMovePlot = true;
                        }
                    }
                    else {
                        let newX1 = chart.leftVScaleWidth;
                        let newY1 = newX1 * chart.kChart + newB;
                        let newX2 = chart.size.cx - chart.rightVScaleWidth;
                        let newY2 = newX2 * chart.kChart + newB;
                        chart.startMovePlot = selectLine(chart, mp, newX1, newY1, newX2, newY2);
                    }
                }
            }
            else if (plot.plotType == "LRLine") {
                chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2);
            }
            else if (plot.plotType == "Segment") {
                chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2);
            }
            else if (plot.plotType == "Ray") {
                chart.startMovePlot = selectRay(chart, mp, mpx1, mpy1, mpx2, mpy2);
            }
            else if (plot.plotType == "Triangle") {
                chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2);
                if (!chart.startMovePlot) {
                    chart.startMovePlot = selectSegment(chart, mp, mpx2, mpy2, mpx3, mpy3);
                }
                if (!chart.startMovePlot) {
                    chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx3, mpy3);
                }
            }
            else if (plot.plotType == "SymmetricTriangle") {
                if (mpx2 != mpx1) {
                    let a = (mpy2 - mpy1) / (mpx2 - mpx1);
                    let b = mpy1 - a * mpx1;
                    let c = -a;
                    let d = mpy3 - c * mpx3;
                    let leftX = chart.leftVScaleWidth;
                    let leftY = leftX * a + b;
                    let rightX = chart.size.cx - chart.rightVScaleWidth;
                    let rightY = rightX * a + b;
                    chart.startMovePlot = selectSegment(chart, mp, leftX, leftY, rightX, rightY);
                    if (!chart.startMovePlot) {
                        leftY = leftX * c + d;
                        rightY = rightX * c + d;
                        chart.startMovePlot = selectSegment(chart, mp, leftX, leftY, rightX, rightY);
                    }
                }
                else {
                    let divHeight = getCandleDivHeight(chart);
                    chart.startMovePlot = selectSegment(chart, mp, mpx1, 0, mpx1, divHeight);
                    if (!chart.startMovePlot) {
                        chart.startMovePlot = selectSegment(chart, mp, mpx3, 0, mpx3, divHeight);
                    }
                }
            }
            else if (plot.plotType == "Rect") {
                let sX1 = Math.min(mpx1, mpx2);
                let sY1 = Math.min(mpy1, mpy2);
                let sX2 = Math.max(mpx1, mpx2);
                let sY2 = Math.max(mpy1, mpy2);
                chart.startMovePlot = selectSegment(chart, mp, sX1, sY1, sX2, sY1);
                if (!chart.startMovePlot) {
                    chart.startMovePlot = selectSegment(chart, mp, sX2, sY1, sX2, sY2);
                }
                if (!chart.startMovePlot) {
                    chart.startMovePlot = selectSegment(chart, mp, sX1, sY2, sX2, sY2);
                }
                if (!chart.startMovePlot) {
                    chart.startMovePlot = selectSegment(chart, mp, sX1, sY1, sX1, sY2);
                }
            }
            else if (plot.plotType == "BoxLine") {
                let sX1 = Math.min(mpx1, mpx2);
                let sY1 = Math.min(mpy1, mpy2);
                let sX2 = Math.max(mpx1, mpx2);
                let sY2 = Math.max(mpy1, mpy2);
                chart.startMovePlot = selectSegment(chart, mp, sX1, sY1, sX2, sY1);
                if (!chart.startMovePlot) {
                    chart.startMovePlot = selectSegment(chart, mp, sX2, sY1, sX2, sY2);
                }
                if (!chart.startMovePlot) {
                    chart.startMovePlot = selectSegment(chart, mp, sX1, sY2, sX2, sY2);
                }
                if (!chart.startMovePlot) {
                    chart.startMovePlot = selectSegment(chart, mp, sX1, sY1, sX1, sY2);
                }
            }
            else if (plot.plotType == "TironeLevels") {
                let sX1 = Math.min(mpx1, mpx2);
                let sY1 = Math.min(mpy1, mpy2);
                let sX2 = Math.max(mpx1, mpx2);
                let sY2 = Math.max(mpy1, mpy2);
                chart.startMovePlot = selectSegment(chart, mp, sX1, sY1, sX2, sY1);
                if (!chart.startMovePlot) {
                    chart.startMovePlot = selectSegment(chart, mp, sX1, sY2, sX2, sY2);
                }
            }
            else if (plot.plotType == "QuadrantLines") {
                let sX1 = Math.min(mpx1, mpx2);
                let sY1 = Math.min(mpy1, mpy2);
                let sX2 = Math.max(mpx1, mpx2);
                let sY2 = Math.max(mpy1, mpy2);
                chart.startMovePlot = selectSegment(chart, mp, sX1, sY1, sX2, sY1);
                if (!chart.startMovePlot) {
                    chart.startMovePlot = selectSegment(chart, mp, sX1, sY2, sX2, sY2);
                }
            }
            else if (plot.plotType == "GoldenRatio") {
                let sX1 = Math.min(mpx1, mpx2);
                let sY1 = Math.min(mpy1, mpy2);
                let sX2 = Math.max(mpx1, mpx2);
                let sY2 = Math.max(mpy1, mpy2);
                let ranges = new Array();
                ranges.push(0);
                ranges.push(0.236);
                ranges.push(0.382);
                ranges.push(0.5);
                ranges.push(0.618);
                ranges.push(0.809);
                ranges.push(1);
                ranges.push(1.382);
                ranges.push(1.618);
                ranges.push(2);
                ranges.push(2.382);
                ranges.push(2.618);
                let minValue = Math.min(plot.value1, plot.value2);
                let maxValue = Math.max(plot.value1, plot.value2);
                for (let j = 0; j < ranges.length; j++) {
                    let newY = sY1 <= sY2 ? sY1 + (sY2 - sY1) * ranges[j] : sY2 + (sY1 - sY2) * (1 - ranges[j]);
                    chart.startMovePlot = selectSegment(chart, mp, chart.leftVScaleWidth, newY, chart.size.cx - chart.rightVScaleWidth, newY);
                    if (chart.startMovePlot) {
                        break;
                    }
                }
            }
            else if (plot.plotType == "Cycle") {
                let r = Math.sqrt(Math.abs((mpx2 - mpx1) * (mpx2 - mpx1) + (mpy2 - mpy1) * (mpy2 - mpy1)));
                let round = (mp.x - mpx1) * (mp.x - mpx1) + (mp.y - mpy1) * (mp.y - mpy1);
                if (round / (r * r) >= 0.9 && round / (r * r) <= 1.1) {
                    chart.startMovePlot = true;
                }
            }
            else if (plot.plotType == "CircumCycle") {
                ellipseOR(chart, mpx1, mpy1, mpx2, mpy2, mpx3, mpy3);
                let round = (mp.x - chart.oXChart) * (mp.x - chart.oXChart) + (mp.y - chart.oYChart) * (mp.y - chart.oYChart);
                if (round / (chart.rChart * chart.rChart) >= 0.9 && round / (chart.rChart * chart.rChart) <= 1.1) {
                    chart.startMovePlot = true;
                }
            }
            else if (plot.plotType == "Ellipse") {
                let x1 = 0, y1 = 0, x2 = 0, y2 = 0;
                if (mpx1 <= mpx2) {
                    x1 = mpx2;
                    y1 = mpy2;
                    x2 = mpx1;
                    y2 = mpy1;
                }
                else {
                    x1 = mpx1;
                    y1 = mpy1;
                    x2 = mpx2;
                    y2 = mpy2;
                }
                let x = x1 - (x1 - x2);
                let y = 0;
                let width = (x1 - x2) * 2;
                let height = 0;
                if (y1 >= y2) {
                    height = (y1 - y2) * 2;
                }
                else {
                    height = (y2 - y1) * 2;
                }
                y = y2 - height / 2;
                let a = width / 2;
                let b = height / 2;
                chart.startMovePlot = ellipseHasPoint(mp.x, mp.y, x + (width / 2), y + (height / 2), a, b);
            }
            else if (plot.plotType == "LRBand") {
                chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2);
                if (!chart.startMovePlot) {
                    let list = new Array();
                    let minIndex = Math.min(index1, index2);
                    let maxIndex = Math.max(index1, index2);
                    for (let j = minIndex; j <= maxIndex; j++) {
                        list.push(chart.data[j].close);
                    }
                    linearRegressionEquation(chart, list);
                    getLRBandRange(chart, plot, chart.kChart, chart.bChart);
                    mpy1 = getChartY(chart, 0, plot.value1 + chart.upSubValue);
                    mpy2 = getChartY(chart, 0, plot.value2 + chart.upSubValue);
                    chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2);
                    if (!chart.startMovePlot) {
                        mpy1 = getChartY(chart, 0, plot.value1 - chart.downSubValue);
                        mpy2 = getChartY(chart, 0, plot.value2 - chart.downSubValue);
                        chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2);
                    }
                }
            }
            else if (plot.plotType == "LRChannel") {
                lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0);
                let rightX = chart.size.cx - chart.rightVScaleWidth;
                let rightY = rightX * chart.kChart + chart.bChart;
                chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, rightX, rightY);
                if (!chart.startMovePlot) {
                    let list = new Array();
                    let minIndex = Math.min(index1, index2);
                    let maxIndex = Math.max(index1, index2);
                    for (let j = minIndex; j <= maxIndex; j++) {
                        list.push(chart.data[j].close);
                    }
                    linearRegressionEquation(chart, list);
                    getLRBandRange(chart, plot, chart.kChart, chart.bChart);
                    mpy1 = getChartY(chart, 0, plot.value1 + chart.upSubValue);
                    mpy2 = getChartY(chart, 0, plot.value2 + chart.upSubValue);
                    lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0);
                    rightY = rightX * chart.kChart + chart.bChart;
                    chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, rightX, rightY);
                    if (!chart.startMovePlot) {
                        mpy1 = getChartY(chart, 0, plot.value1 - chart.downSubValue);
                        mpy2 = getChartY(chart, 0, plot.value2 - chart.downSubValue);
                        lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0);
                        rightY = rightX * chart.kChart + chart.bChart;
                        chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, rightX, rightY);
                    }
                }
            }
            else if (plot.plotType == "ParalleGram") {
                parallelogram(chart, mpx1, mpy1, mpx2, mpy2, mpx3, mpy3);
                chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2);
                if (!chart.startMovePlot) {
                    chart.startMovePlot = selectSegment(chart, mp, mpx2, mpy2, mpx3, mpy3);
                    if (!chart.startMovePlot) {
                        chart.startMovePlot = selectSegment(chart, mp, mpx3, mpy3, chart.x4Chart, chart.y4Chart);
                        if (!chart.startMovePlot) {
                            chart.startMovePlot = selectSegment(chart, mp, chart.x4Chart, chart.y4Chart, mpx1, mpy1);
                        }
                    }
                }
            }
            else if (plot.plotType == "SpeedResist") {
                chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2);
                if (!chart.startMovePlot) {
                    if (mpx1 != mpx2 && mpy1 != mpy2) {
                        let firstP = new FCPoint(mpx2, mpy2 - (mpy2 - mpy1) / 3);
                        let secondP = new FCPoint(mpx2, mpy2 - (mpy2 - mpy1) * 2 / 3);
                        let startP = new FCPoint(mpx1, mpy1);
                        let fK = 0, fB = 0, sK = 0, sB = 0;
                        lineXY(chart, startP.x, startP.y, firstP.x, firstP.y, 0, 0);
                        fK = chart.kChart;
                        fB = chart.bChart;
                        lineXY(chart, startP.x, startP.y, secondP.x, secondP.y, 0, 0);
                        sK = chart.kChart;
                        sB = chart.bChart;
                        let newYF = 0, newYS = 0;
                        let newX = 0;
                        if (mpx2 > mpx1) {
                            newYF = fK * (chart.size.cx - chart.rightVScaleWidth) + fB;
                            newYS = sK * (chart.size.cx - chart.rightVScaleWidth) + sB;
                            newX = (chart.size.cx - chart.rightVScaleWidth);
                        }
                        else {
                            newYF = fB;
                            newYS = sB;
                            newX = chart.leftVScaleWidth;
                        }
                        chart.startMovePlot = selectSegment(chart, mp, startP.x, startP.y, newX, newYF);
                        if (!chart.startMovePlot) {
                            chart.startMovePlot = selectSegment(chart, mp, startP.x, startP.y, newX, newYS);
                        }
                    }
                }
            }
            else if (plot.plotType == "FiboFanline") {
                chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2);
                if (!chart.startMovePlot) {
                    if (mpx1 != mpx2 && mpy1 != mpy2) {
                        let firstP = new FCPoint(mpx2, mpy2 - (mpy2 - mpy1) * 0.382);
                        let secondP = new FCPoint(mpx2, mpy2 - (mpy2 - mpy1) * 0.5);
                        let thirdP = new FCPoint(mpx2, mpy2 - (mpy2 - mpy1) * 0.618);
                        let startP = new FCPoint(mpx1, mpy1);
                        let listP = new Array();
                        listP.push(firstP);
                        listP.push(secondP);
                        listP.push(thirdP);
                        let listSize = listP.length;
                        for (let j = 0; j < listSize; j++) {
                            lineXY(chart, startP.x, startP.y, listP[j].x, listP[j].y, 0, 0);
                            let newX = 0;
                            let newY = 0;
                            if (mpx2 > mpx1) {
                                newY = chart.kChart * (chart.size.cx - chart.rightVScaleWidth) + chart.bChart;
                                newX = (chart.size.cx - chart.rightVScaleWidth);
                            }
                            else {
                                newY = chart.bChart;
                                newX = chart.leftVScaleWidth;
                            }
                            chart.startMovePlot = selectSegment(chart, mp, startP.x, startP.y, newX, newY);
                            if (chart.startMovePlot) {
                                break;
                            }
                        }
                    }
                }
            }
            else if (plot.plotType == "FiboTimezone") {
                let fValue = 1;
                let aIndex = index1;
                let pos = 1;
                let divHeight = getCandleDivHeight(chart);
                chart.startMovePlot = selectSegment(chart, mp, mpx1, 0, mpx1, divHeight);
                if (!chart.startMovePlot) {
                    while (aIndex + fValue <= chart.lastVisibleIndex) {
                        fValue = fibonacciValue(pos);
                        let newIndex = aIndex + fValue;
                        let newX = getChartX(chart, newIndex);
                        chart.startMovePlot = selectSegment(chart, mp, newX, 0, newX, divHeight);
                        if (chart.startMovePlot) {
                            break;
                        }
                        pos++;
                    }
                }
            }
            else if (plot.plotType == "Percent") {
                let list = getPercentParams(mpy1, mpy2);
                for (let j = 0; j < list.length; j++) {
                    chart.startMovePlot = selectSegment(chart, mp, chart.leftVScaleWidth, list[j], chart.size.cx - chart.rightVScaleWidth, list[j]);
                    if (chart.startMovePlot) {
                        break;
                    }
                }
            }
            if (chart.startMovePlot) {
                sPlot = plot;
                plot.startKey1 = plot.key1;
                plot.startValue1 = plot.value1;
                plot.startKey2 = plot.key2;
                plot.startValue2 = plot.value2;
                plot.startKey3 = plot.key3;
                plot.startValue3 = plot.value3;
                break;
            }
        }
    }
    return sPlot;
}
/*
* 计算线性回归上下限
* chart:图表
* plot:画线
* a:直线k
* b:直线b
*/
function getLRBandRange(chart, plot, a, b) {
    let bIndex = getChartIndexByDate(chart, plot.key1);
    let eIndex = getChartIndexByDate(chart, plot.key2);
    let tempBIndex = Math.min(bIndex, eIndex);
    let tempEIndex = Math.max(bIndex, eIndex);
    bIndex = tempBIndex;
    eIndex = tempEIndex;
    let upList = new Array();
    let downList = new Array();
    for (let i = bIndex; i <= eIndex; i++) {
        let high = chart.data[i].high;
        let low = chart.data[i].low;
        let midValue = (i - bIndex + 1) * a + b;
        upList.push(high - midValue);
        downList.push(midValue - low);
    }
    chart.upSubValue = maxValue(upList);
    chart.downSubValue = maxValue(downList);
}
/*
* 根据位置计算索引
* chart:图表
* mp:坐标
*/
function getChartIndex(chart, mp) {
    if (chart.data && chart.data.length == 0) {
        return -1;
    }
    if (mp.x <= 0) {
        return 0;
    }
    let intX = Math.floor(mp.x - chart.leftVScaleWidth - chart.hScalePixel - chart.offsetX);
    if (intX < 0) {
        intX = 0;
    }
    let index = Math.floor(chart.firstVisibleIndex + intX / chart.hScalePixel);
    if (intX % chart.hScalePixel != 0) {
        index++;
    }
    if (index < 0) {
        index = 0;
    }
    else if (chart.data && index > chart.data.length - 1) {
        index = chart.data.length - 1;
    }
    return index;
}
/*
* 获取最大显示记录条数
* chart:图表
* hScalePixel:间隔
* pureH:横向距离
*/
function getChartMaxVisibleCount(chart, hScalePixel, pureH) {
    let count = Math.floor(pureH / hScalePixel);
    if (count < 0) {
        count = 0;
    }
    return count;
}
/*
* 获取图表层的高度
* chart:图表
*/
function getCandleDivHeight(chart) {
    let height = chart.size.cy - chart.hScaleHeight;
    if (height > 0) {
        return height * chart.candleDivPercent;
    }
    else {
        return 0;
    }
}
/*
* 获取成交量层的高度
* chart:图表
*/
function getVolDivHeight(chart) {
    let height = chart.size.cy - chart.hScaleHeight;
    if (height > 0) {
        return height * chart.volDivPercent;
    }
    else {
        return 0;
    }
}
/*
* 获取指标层的高度
* chart:图表
*/
function getIndDivHeight(chart) {
    let height = chart.size.cy - chart.hScaleHeight;
    if (height > 0) {
        return height * chart.indDivPercent;
    }
    else {
        return 0;
    }
}
/*
* 获取指标层2的高度
* chart:图表
*/
function getIndDivHeight2(chart) {
    let height = chart.size.cy - chart.hScaleHeight;
    if (height > 0) {
        return height * chart.indDivPercent2;
    }
    else {
        return 0;
    }
}
/*
* 获取横向工作区
* chart:图表
*/
function getChartWorkAreaWidth(chart) {
    return chart.size.cx - chart.leftVScaleWidth - chart.rightVScaleWidth - chart.rightSpace - chart.offsetX;
}
/*
* 根据索引获取横坐标
* chart:图表
* index:索引
*/
function getChartX(chart, index) {
    return chart.leftVScaleWidth + (index - chart.firstVisibleIndex) * chart.hScalePixel + chart.hScalePixel / 2 + chart.offsetX;
}
/*
* 根据日期获取索引
* chart:图表
* date:日期
*/
function getChartIndexByDate(chart, date) {
    let index = -1;
    for (let i = 0; i < chart.data.length; i++) {
        if (chart.data[i].date == date) {
            index = i;
            break;
        }
    }
    return index;
}
/*
* 根据索引获取日期
* chart:图表
* index:索引
*/
function getChartDateByIndex(chart, index) {
    let date = 0;
    if (index >= 0 && index < chart.data.length) {
        date = chart.data[index].date;
    }
    return date;
}
/*
* 计算数值在层中的位置
* chart:图表
* divIndex:所在层
* chart:数值
*/
function getChartY(chart, divIndex, value) {
    if (divIndex == 0) {
        if (chart.candleMax > chart.candleMin) {
            let cValue = value, cMax = chart.candleMax, cMin = chart.candleMin;
            if (chart.vScaleType != "standard") {
                if (cValue > 0) {
                    cValue = Math.log10(cValue);
                }
                else if (cValue < 0) {
                    cValue = -Math.log10(Math.abs(cValue));
                }
                if (cMax > 0) {
                    cMax = Math.log10(cMax);
                }
                else if (cMax < 0) {
                    cMax = -Math.log10(Math.abs(cMax));
                }
                if (cMin > 0) {
                    cMin = Math.log10(cMin);
                }
                else if (cMin < 0) {
                    cMin = -Math.log10(Math.abs(cMin));
                }
            }
            let rate = (cValue - cMin) / (cMax - cMin);
            let divHeight = getCandleDivHeight(chart);
            return divHeight - chart.candlePaddingBottom - (divHeight - chart.candlePaddingTop - chart.candlePaddingBottom) * rate;
        }
        else {
            return 0;
        }
    }
    else if (divIndex == 1) {
        if (chart.volMax > chart.volMin) {
            let rate = (value - chart.volMin) / (chart.volMax - chart.volMin);
            let candleHeight = getCandleDivHeight(chart);
            let volHeight = getVolDivHeight(chart);
            return candleHeight + volHeight - chart.volPaddingBottom - (volHeight - chart.volPaddingTop - chart.volPaddingBottom) * rate;
        }
        else {
            return 0;
        }
    }
    else if (divIndex == 2) {
        if (chart.indMax > chart.indMin) {
            let rate = (value - chart.indMin) / (chart.indMax - chart.indMin);
            let candleHeight = getCandleDivHeight(chart);
            let volHeight = getVolDivHeight(chart);
            let indHeight = getIndDivHeight(chart);
            return candleHeight + volHeight + indHeight - chart.indPaddingBottom - (indHeight - chart.indPaddingTop - chart.indPaddingBottom) * rate;
        }
        else {
            return 0;
        }
    }
    else if (divIndex == 3) {
        if (chart.indMax2 > chart.indMin2) {
            let rate = (value - chart.indMin2) / (chart.indMax2 - chart.indMin2);
            let candleHeight = getCandleDivHeight(chart);
            let volHeight = getVolDivHeight(chart);
            let indHeight = getIndDivHeight(chart);
            let indHeight2 = getIndDivHeight2(chart);
            return candleHeight + volHeight + indHeight + indHeight2 - chart.indPaddingBottom2 - (indHeight2 - chart.indPaddingTop2 - chart.indPaddingBottom2) * rate;
        }
        else {
            return 0;
        }
    }
    return 0;
}
/*
* 计算数值在层中的右轴位置
* chart:图表
* divIndex:所在层
* chart:数值
*/
function getChartYInRight(chart, divIndex, value) {
    if (divIndex == 0) {
        if (chart.candleMaxRight > chart.candleMinRight) {
            let cValue = value, cMax = chart.candleMaxRight, cMin = chart.candleMinRight;
            if (chart.vScaleType != "standard") {
                if (cValue > 0) {
                    cValue = Math.log10(cValue);
                }
                else if (cValue < 0) {
                    cValue = -Math.log10(Math.abs(cValue));
                }
                if (cMax > 0) {
                    cMax = Math.log10(cMax);
                }
                else if (cMax < 0) {
                    cMax = -Math.log10(Math.abs(cMax));
                }
                if (cMin > 0) {
                    cMin = Math.log10(cMin);
                }
                else if (cMin < 0) {
                    cMin = -Math.log10(Math.abs(cMin));
                }
            }
            let rate = (cValue - cMin) / (cMax - cMin);
            let divHeight = getCandleDivHeight(chart);
            return divHeight - chart.candlePaddingBottom - (divHeight - chart.candlePaddingTop - chart.candlePaddingBottom) * rate;
        }
        else {
            return 0;
        }
    }
    else if (divIndex == 1) {
        if (chart.volMaxRight > chart.volMinRight) {
            let rate = (value - chart.volMinRight) / (chart.volMaxRight - chart.volMinRight);
            let candleHeight = getCandleDivHeight(chart);
            let volHeight = getVolDivHeight(chart);
            return candleHeight + volHeight - chart.volPaddingBottom - (volHeight - chart.volPaddingTop - chart.volPaddingBottom) * rate;
        }
        else {
            return 0;
        }
    }
    else if (divIndex == 2) {
        if (chart.indMaxRight > chart.indMinRight) {
            let rate = (value - chart.indMinRight) / (chart.indMaxRight - chart.indMinRight);
            let candleHeight = getCandleDivHeight(chart);
            let volHeight = getVolDivHeight(chart);
            let indHeight = getIndDivHeight(chart);
            return candleHeight + volHeight + indHeight - chart.indPaddingBottom - (indHeight - chart.indPaddingTop - chart.indPaddingBottom) * rate;
        }
        else {
            return 0;
        }
    }
    else if (divIndex == 3) {
        if (chart.indMax2Right > chart.indMin2Right) {
            let rate = (value - chart.indMin2Right) / (chart.indMax2Right - chart.indMin2Right);
            let candleHeight = getCandleDivHeight(chart);
            let volHeight = getVolDivHeight(chart);
            let indHeight = getIndDivHeight(chart);
            let indHeight2 = getIndDivHeight2(chart);
            return candleHeight + volHeight + indHeight + indHeight2 - chart.indPaddingBottom2 - (indHeight2 - chart.indPaddingTop2 - chart.indPaddingBottom2) * rate;
        }
        else {
            return 0;
        }
    }
    return 0;
}
/*
* 根据坐标获取对应的值
* chart:图表
* point:坐标
*/
function getChartValue(chart, point) {
    let candleHeight = getCandleDivHeight(chart);
    let volHeight = getVolDivHeight(chart);
    let indHeight = getIndDivHeight(chart);
    let indHeight2 = getIndDivHeight(chart);
    if (point.y <= candleHeight) {
        if (candleHeight - chart.candlePaddingTop - chart.candlePaddingBottom > 0) {
            let rate = (candleHeight - chart.candlePaddingBottom - point.y) / (candleHeight - chart.candlePaddingTop - chart.candlePaddingBottom);
            let cMin = chart.candleMin, cMax = chart.candleMax;
            if (chart.vScaleType != "standard") {
                if (cMax > 0) {
                    cMax = Math.log10(cMax);
                }
                else if (cMax < 0) {
                    cMax = -Math.log10(Math.abs(cMax));
                }
                if (cMin > 0) {
                    cMin = Math.log10(cMin);
                }
                else if (cMin < 0) {
                    cMin = -Math.log10(Math.abs(cMin));
                }
            }
            let result = cMin + (cMax - cMin) * rate;
            if (chart.vScaleType != "standard") {
                return Math.pow(10, result);
            }
            else {
                return result;
            }
        }
    }
    else if (point.y > candleHeight && point.y <= candleHeight + volHeight) {
        if (volHeight - chart.volPaddingTop - chart.volPaddingBottom > 0) {
            let rate = (volHeight - chart.volPaddingBottom - (point.y - candleHeight)) / (volHeight - chart.volPaddingTop - chart.volPaddingBottom);
            return chart.volMin + (chart.volMax - chart.volMin) * rate;
        }
    }
    else if (point.y > candleHeight + volHeight && point.y <= candleHeight + volHeight + indHeight) {
        if (indHeight - chart.indPaddingTop - chart.indPaddingBottom > 0) {
            let rate = (indHeight - chart.indPaddingBottom - (point.y - candleHeight - volHeight)) / (indHeight - chart.indPaddingTop - chart.indPaddingBottom);
            return chart.indMin + (chart.indMax - chart.indMin) * rate;
        }
    }
    else if (point.y > candleHeight + volHeight + indHeight && point.y <= candleHeight + volHeight + indHeight + indHeight2) {
        if (indHeight2 - chart.indPaddingTop2 - chart.indPaddingBottom2 > 0) {
            let rate = (indHeight2 - chart.indPaddingBottom2 - (point.y - candleHeight - volHeight - indHeight)) / (indHeight2 - chart.indPaddingTop2 - chart.indPaddingBottom2);
            return chart.indMin2 + (chart.indMax2 - chart.indMin2) * rate;
        }
    }
    return 0;
}
/*
* 根据坐标获取对应的值
* chart:图表
* point:坐标
*/
function getCandleDivValue(chart, point) {
    let candleHeight = getCandleDivHeight(chart);
    let rate = 0;
    if (candleHeight - chart.candlePaddingTop - chart.candlePaddingBottom > 0) {
        rate = (candleHeight - chart.candlePaddingBottom - point.y) / (candleHeight - chart.candlePaddingTop - chart.candlePaddingBottom);
    }
    let cMin = chart.candleMin, cMax = chart.candleMax;
    if (chart.vScaleType != "standard") {
        if (cMax > 0) {
            cMax = Math.log10(cMax);
        }
        else if (cMax < 0) {
            cMax = -Math.log10(Math.abs(cMax));
        }
        if (cMin > 0) {
            cMin = Math.log10(cMin);
        }
        else if (cMin < 0) {
            cMin = -Math.log10(Math.abs(cMin));
        }
    }
    let result = cMin + (cMax - cMin) * rate;
    if (chart.vScaleType != "standard") {
        return Math.pow(10, result);
    }
    else {
        return result;
    }
}
/*
* 检查最后可见索引
* chart:图表
*/
function checkChartLastVisibleIndex(chart) {
    if (chart.data) {
        let dataCount = chart.data.length;
        let workingAreaWidth = getChartWorkAreaWidth(chart);
        let maxVisibleRecord = getChartMaxVisibleCount(chart, chart.hScalePixel, workingAreaWidth);
        if (chart.firstVisibleIndex < 0) {
            chart.firstVisibleIndex = 0;
        }
        if (chart.lastVisibleIndex >= chart.firstVisibleIndex + maxVisibleRecord - 1 || chart.lastVisibleIndex < dataCount - 1) {
            chart.lastVisibleIndex = chart.firstVisibleIndex + maxVisibleRecord - 1;
        }
        if (chart.lastVisibleIndex > dataCount - 1) {
            chart.lastVisibleIndex = dataCount - 1;
        }
    }
    if (chart.data.length > 0 && chart.lastVisibleIndex != -1) {
        chart.lastVisibleKey = chart.data[chart.lastVisibleIndex].date;
        if (chart.lastVisibleIndex == chart.data.length - 1) {
            chart.lastRecordIsVisible = true;
        }
        else {
            chart.lastRecordIsVisible = false;
        }
    }
    else {
        chart.lastVisibleKey = 0;
        chart.lastRecordIsVisible = true;
    }
}
/*
* 自动设置首先可见和最后可见的记录号
* chart:图表
*/
function resetChartVisibleRecord(chart) {
    let rowsCount = chart.data.length;
    let workingAreaWidth = getChartWorkAreaWidth(chart);
    if (chart.autoFillHScale) {
        if (workingAreaWidth > 0 && rowsCount > 0) {
            chart.hScalePixel = workingAreaWidth / rowsCount;
            chart.firstVisibleIndex = 0;
            chart.lastVisibleIndex = rowsCount - 1;
        }
    }
    else {
        let maxVisibleRecord = getChartMaxVisibleCount(chart, chart.hScalePixel, workingAreaWidth);
        //没数据时重置
        if (rowsCount == 0) {
            chart.firstVisibleIndex = -1;
            chart.lastVisibleIndex = -1;
        }
        else {
            //数据不足一屏时
            if (rowsCount < maxVisibleRecord) {
                chart.lastVisibleIndex = rowsCount - 1;
                chart.firstVisibleIndex = 0;
            }
            //数据超过一屏时
            else {
                //显示中间的数据时
                if (chart.firstVisibleIndex != -1 && chart.lastVisibleIndex != -1 && !chart.lastRecordIsVisible) {
                    let index = getChartIndexByDate(chart, chart.lastVisibleKey);
                    if (index != -1) {
                        chart.lastVisibleIndex = index;
                    }
                    chart.firstVisibleIndex = chart.lastVisibleIndex - maxVisibleRecord + 1;
                    if (chart.firstVisibleIndex < 0) {
                        chart.firstVisibleIndex = 0;
                        chart.lastVisibleIndex = chart.firstVisibleIndex + maxVisibleRecord;
                        checkChartLastVisibleIndex(chart);
                    }
                }
                else {
                    //第一条或最后一条数据被显示时
                    chart.lastVisibleIndex = rowsCount - 1;
                    chart.firstVisibleIndex = chart.lastVisibleIndex - maxVisibleRecord + 1;
                    if (chart.firstVisibleIndex > chart.lastVisibleIndex) {
                        chart.firstVisibleIndex = chart.lastVisibleIndex;
                    }
                }
            }
        }
    }
}
/*
* 设置可见索引
* chart:图表
* firstVisibleIndex:起始索引
* lastVisibleIndex:结束索引
*/
function setChartVisibleIndex(chart, firstVisibleIndex, lastVisibleIndex) {
    let xScalePixel = getChartWorkAreaWidth(chart) / (lastVisibleIndex - firstVisibleIndex + 1);
    if (xScalePixel < 1000000) {
        chart.firstVisibleIndex = firstVisibleIndex;
        chart.lastVisibleIndex = lastVisibleIndex;
        //设置最后一条记录是否可见
        if (lastVisibleIndex != chart.data.length - 1) {
            chart.lastRecordIsVisible = false;
        }
        else {
            chart.lastRecordIsVisible = true;
        }
        chart.hScalePixel = xScalePixel;
        checkChartLastVisibleIndex(chart);
    }
}
/*
* 清除图形
* chart:图表
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawChart(chart, paint, clipRect) {
    if (chart.backColor && chart.backColor != "none") {
        paint.fillRect(chart.backColor, 0, 0, chart.size.cx, chart.size.cy);
    }
    if (chart.onPaintChartScale) {
        chart.onPaintChartScale(chart, paint, clipRect);
    }
    else if (paint.onPaintChartScale) {
        paint.onPaintChartScale(chart, paint, clipRect);
    }
    else {
        drawChartScale(chart, paint, clipRect);
    }
    if (chart.onPaintChartStock) {
        chart.onPaintChartStock(chart, paint, clipRect);
    }
    else if (paint.onPaintChartStock) {
        paint.onPaintChartStock(chart, paint, clipRect);
    }
    else {
        drawChartStock(chart, paint, clipRect);
    }
    if (chart.onPaintChartPlot) {
        chart.onPaintChartPlot(chart, paint, clipRect);
    }
    else if (paint.onPaintChartPlot) {
        paint.onPaintChartPlot(chart, paint, clipRect);
    }
    else {
        drawChartPlot(chart, paint, clipRect);
    }
    if (chart.onPaintChartCrossLine) {
        chart.onPaintChartCrossLine(chart, paint, clipRect);
    }
    else if (paint.onPaintChartCrossLine) {
        paint.onPaintChartCrossLine(chart, paint, clipRect);
    }
    else {
        drawChartCrossLine(chart, paint, clipRect);
    }
    if (chart.borderColor && chart.borderColor != "none") {
        paint.drawRect(chart.borderColor, chart.lineWidthChart, null, 0, 0, chart.size.cx, chart.size.cy);
    }
}
/*
* 计算坐标轴
* min:最小值
* max:最大值
* yLen:长度
* maxSpan:最大间隔
* minSpan:最小间隔
* defCount:数量
*/
function chartGridScale(chart, min, max, yLen, maxSpan, minSpan, defCount) {
    chart.gridStepChart = 0;
    chart.gridDigitChart = 0;
    if (defCount == 0) {
        return 0;
    }
    let sub = max - min;
    let nMinCount = Math.floor(Math.ceil(yLen / maxSpan));
    let nMaxCount = Math.floor(Math.floor(yLen / minSpan));
    let nCount = defCount;
    let logStep = sub / nCount;
    let start = false;
    let divisor = 0;
    let i = 0, nTemp = 0;
    nCount = Math.max(nMinCount, nCount);
    nCount = Math.min(nMaxCount, nCount);
    nCount = Math.max(nCount, 1);
    for (i = 15; i >= -6; i--) {
        divisor = Math.pow(10.0, i);
        if (divisor < 1) {
            chart.gridDigitChart++;
        }
        nTemp = Math.floor(Math.floor(logStep / divisor));
        if (start) {
            if (nTemp < 4) {
                if (chart.gridDigitChart > 0) {
                    chart.gridDigitChart--;
                }
            }
            else if (nTemp >= 4 && nTemp <= 6) {
                nTemp = 5;
                chart.gridStepChart += nTemp * divisor;
            }
            else {
                chart.gridStepChart += 10 * divisor;
                if (chart.gridDigitChart > 0) {
                    chart.gridDigitChart--;
                }
            }
            break;
        }
        else if (nTemp > 0) {
            chart.gridStepChart = nTemp * divisor + chart.gridStepChart;
            logStep -= chart.gridStepChart;
            start = true;
        }
    }
    return 0;
}
/*
* 缩小
* chart:图表
*/
function zoomOutChart(chart) {
    if (!chart.autoFillHScale) {
        let hScalePixel = chart.hScalePixel;
        let oldX = getChartX(chart, chart.crossStopIndex);
        if (chart.showCrossLine && chart.targetOldX == 0) {
            chart.targetOldX = oldX;
        }
        let pureH = getChartWorkAreaWidth(chart);
        let oriMax = -1, max = -1, deal = 0;
        let dataCount = chart.data.length;
        let findex = chart.firstVisibleIndex, lindex = chart.lastVisibleIndex;
        if (hScalePixel < pureH) {
            oriMax = getChartMaxVisibleCount(chart, hScalePixel, pureH);
            if (dataCount < oriMax) {
                deal = 1;
            }
            if (hScalePixel > 3) {
                hScalePixel += 1;
            }
            else {
                if (hScalePixel == 1) {
                    hScalePixel = 2;
                }
                else {
                    hScalePixel = hScalePixel * 1.5;
                    if (hScalePixel > 3) {
                        hScalePixel = Math.floor(hScalePixel);
                    }
                }
            }
            max = getChartMaxVisibleCount(chart, hScalePixel, pureH);
            if (dataCount >= max) {
                if (deal == 1) {
                    lindex = dataCount - 1;
                }
                findex = lindex - max + 1;
                if (findex < 0) {
                    findex = 0;
                }
            }
        }
        chart.hScalePixel = hScalePixel;
        if (chart.showCrossLine) {
            let sX = chart.targetOldX;
            findex = chart.crossStopIndex;
            while (sX >= chart.leftVScaleWidth + chart.hScalePixel / 2) {
                findex = findex - 1;
                chart.offsetX = sX - chart.leftVScaleWidth - chart.hScalePixel / 2;
                sX = sX - chart.hScalePixel;
            }
            findex = findex + 1;
        }
        chart.firstVisibleIndex = findex;
        chart.lastVisibleIndex = lindex;
        checkChartLastVisibleIndex(chart);
        if (chart.onCalculateChartMaxMin) {
            chart.onCalculateChartMaxMin(chart);
        }
        else if (chart.paint.onCalculateChartMaxMin) {
            chart.paint.onCalculateChartMaxMin(chart);
        }
        else {
            calculateChartMaxMin(chart);
        }
    }
}
/*
* 放大
* chart:图表
*/
function zoomInChart(chart) {
    if (!chart.autoFillHScale) {
        let hScalePixel = chart.hScalePixel;
        let oldX = getChartX(chart, chart.crossStopIndex);
        if (chart.showCrossLine && chart.targetOldX2 == 0) {
            chart.targetOldX2 = oldX;
        }
        let pureH = getChartWorkAreaWidth(chart);
        let max = -1;
        let dataCount = chart.data.length;
        let findex = chart.firstVisibleIndex, lindex = chart.lastVisibleIndex;
        if (hScalePixel > 3) {
            hScalePixel -= 1;
        }
        else {
            hScalePixel = hScalePixel * 2 / 3;
            if (hScalePixel > 3) {
                hScalePixel = Math.floor(hScalePixel);
            }
        }
        max = getChartMaxVisibleCount(chart, hScalePixel, pureH);
        if (max >= dataCount) {
            if (hScalePixel < 1) {
                hScalePixel = pureH / max;
            }
            findex = 0;
            lindex = dataCount - 1;
        }
        else {
            findex = lindex - max + 1;
            if (findex < 0) {
                findex = 0;
            }
        }
        chart.hScalePixel = hScalePixel;
        if (chart.showCrossLine) {
            let sX = chart.targetOldX2;
            findex = chart.crossStopIndex;
            while (sX >= chart.leftVScaleWidth + chart.hScalePixel / 2) {
                findex = findex - 1;
                chart.offsetX = sX - chart.leftVScaleWidth - chart.hScalePixel / 2;
                sX = sX - chart.hScalePixel;
            }
            findex = findex + 1;
        }
        chart.firstVisibleIndex = findex;
        chart.lastVisibleIndex = lindex;
        checkChartLastVisibleIndex(chart);
        if (chart.onCalculateChartMaxMin) {
            chart.onCalculateChartMaxMin(chart);
        }
        else if (chart.paint.onCalculateChartMaxMin) {
            chart.paint.onCalculateChartMaxMin(chart);
        }
        else {
            calculateChartMaxMin(chart);
        }
    }
}
/*
* 绘制刻度
* chart:图表
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawChartScale(chart, paint, clipRect) {
    if (chart.leftVScaleWidth > 0) {
        paint.drawLine(chart.scaleColor, chart.lineWidthChart, null, chart.leftVScaleWidth, 0, chart.leftVScaleWidth, chart.size.cy - chart.hScaleHeight);
    }
    if (chart.rightVScaleWidth > 0) {
        paint.drawLine(chart.scaleColor, chart.lineWidthChart, null, chart.size.cx - chart.rightVScaleWidth, 0, chart.size.cx - chart.rightVScaleWidth, chart.size.cy - chart.hScaleHeight);
    }
    if (chart.hScaleHeight > 0) {
        paint.drawLine(chart.scaleColor, chart.lineWidthChart, null, 0, chart.size.cy - chart.hScaleHeight, chart.size.cx, chart.size.cy - chart.hScaleHeight);
    }
    let candleDivHeight = getCandleDivHeight(chart);
    let volDivHeight = getVolDivHeight(chart);
    let indDivHeight = getIndDivHeight(chart);
    let indDivHeight2 = getIndDivHeight2(chart);
    if (volDivHeight > 0) {
        paint.drawLine(chart.scaleColor, chart.lineWidthChart, null, chart.leftVScaleWidth, candleDivHeight, chart.size.cx - chart.rightVScaleWidth, candleDivHeight);
    }
    if (indDivHeight > 0) {
        paint.drawLine(chart.scaleColor, chart.lineWidthChart, null, chart.leftVScaleWidth, candleDivHeight + volDivHeight, chart.size.cx - chart.rightVScaleWidth, candleDivHeight + volDivHeight);
    }
    if (indDivHeight2 > 0) {
        paint.drawLine(chart.scaleColor, chart.lineWidthChart, null, chart.leftVScaleWidth, candleDivHeight + volDivHeight + indDivHeight, chart.size.cx - chart.rightVScaleWidth, candleDivHeight + volDivHeight + indDivHeight);
    }
    let topPoint = new FCPoint(0, 20);
    let bottomPoint = new FCPoint(0, candleDivHeight - 10);
    let candleMax = getChartValue(chart, topPoint);
    let candleMin = getChartValue(chart, bottomPoint);
    chartGridScale(chart, candleMin, candleMax, (candleDivHeight - chart.candlePaddingTop - chart.candlePaddingBottom) / 2, chart.vScaleDistance, chart.vScaleDistance / 2, Math.floor((candleDivHeight - chart.candlePaddingTop - chart.candlePaddingBottom) / chart.vScaleDistance));
    if (chart.gridStepChart > 0) {
        let drawValues = new Array();
        let isTrend = chart.cycle == "trend";
        let firstOpen = chart.firstOpen;
        if (isTrend) {
            if (firstOpen == 0) {
                firstOpen = chart.data[chart.firstVisibleIndex].close;
            }
            let subValue = (candleMax - candleMin);
            let count = (candleDivHeight - chart.candlePaddingTop - chart.candlePaddingBottom) / chart.vScaleDistance;
            if (count > 0) {
                subValue /= count;
            }
            let start = firstOpen;
            while (start < candleMax) {
                start += subValue;
                if (start <= candleMax) {
                    drawValues.push(start);
                }
            }
            start = firstOpen;
            while (start > candleMin) {
                start -= subValue;
                if (start >= candleMin) {
                    drawValues.push(start);
                }
            }
        }
        else {
            let start = 0;
            if (candleMin >= 0) {
                while (start + chart.gridStepChart < candleMin) {
                    start += chart.gridStepChart;
                }
            }
            else {
                while (start - chart.gridStepChart > candleMin) {
                    start -= chart.gridStepChart;
                }
            }
            while (start <= candleMax) {
                if (start > candleMin) {
                    drawValues.push(start);
                }
                start += chart.gridStepChart;
            }
        }
        drawValues.push(firstOpen);
        for (let i = 0; i < drawValues.length; i++) {
            let start = drawValues[i];
            let hAxisY = getChartY(chart, 0, start);
            if (hAxisY < 1 || hAxisY > candleDivHeight) {
                continue;
            }
            paint.drawLine(chart.gridColor, chart.lineWidthChart, null, chart.leftVScaleWidth, Math.floor(hAxisY), chart.size.cx - chart.rightVScaleWidth, Math.floor(hAxisY));
            paint.drawLine(chart.scaleColor, chart.lineWidthChart, null, chart.leftVScaleWidth - 8, Math.floor(hAxisY), chart.leftVScaleWidth, Math.floor(hAxisY));
            paint.drawLine(chart.scaleColor, chart.lineWidthChart, null, chart.size.cx - chart.rightVScaleWidth, Math.floor(hAxisY), chart.size.cx - chart.rightVScaleWidth + 8, Math.floor(hAxisY));
            let drawText = start.toFixed(chart.candleDigit);
            let tSize = paint.textSize(drawText, chart.font);
            if (isTrend) {
                let diffRange = ((start - firstOpen) / firstOpen * 100);
                let diffRangeStr = diffRange.toFixed(2) + "%";
                if (diffRange >= 0) {
                    paint.drawText(diffRangeStr, chart.upColor, chart.font, chart.size.cx - chart.rightVScaleWidth + 10, Math.floor(hAxisY) - tSize.cy / 2);
                }
                else {
                    paint.drawText(diffRangeStr, chart.downColor, chart.font, chart.size.cx - chart.rightVScaleWidth + 10, Math.floor(hAxisY) - tSize.cy / 2);
                }
            }
            else {
                if (chart.vScaleTextColor != "none") {
                    paint.drawText(drawText, chart.vScaleTextColor, chart.font, chart.size.cx - chart.rightVScaleWidth + 10, Math.floor(hAxisY) - tSize.cy / 2);
                }
                else {
                    paint.drawText(drawText, chart.textColor, chart.font, chart.size.cx - chart.rightVScaleWidth + 10, Math.floor(hAxisY) - tSize.cy / 2);
                }
            }
            if (chart.vScaleTextColor != "none") {
                paint.drawText(drawText, chart.vScaleTextColor, chart.font, chart.leftVScaleWidth - tSize.cx - 10, Math.floor(hAxisY) - tSize.cy / 2);
            }
            else {
                paint.drawText(drawText, chart.textColor, chart.font, chart.leftVScaleWidth - tSize.cx - 10, Math.floor(hAxisY) - tSize.cy / 2);
            }
        }
    }
    topPoint = new FCPoint(0, candleDivHeight + 10);
    bottomPoint = new FCPoint(0, candleDivHeight + volDivHeight - 10);
    let volMax = getChartValue(chart, topPoint);
    let volMin = getChartValue(chart, bottomPoint);
    chartGridScale(chart, volMin, volMax, (volDivHeight - chart.volPaddingTop - chart.volPaddingBottom) / 2, chart.vScaleDistance, chart.vScaleDistance / 2, Math.floor((volDivHeight - chart.volPaddingTop - chart.volPaddingBottom) / chart.vScaleDistance));
    if (chart.gridStepChart > 0) {
        let start = 0;
        if (volMin >= 0) {
            while (start + chart.gridStepChart < volMin) {
                start += chart.gridStepChart;
            }
        }
        else {
            while (start - chart.gridStepChart > volMin) {
                start -= chart.gridStepChart;
            }
        }
        while (start <= volMax) {
            if (start > volMin) {
                let hAxisY = getChartY(chart, 1, start);
                if (hAxisY < candleDivHeight || hAxisY > candleDivHeight + volDivHeight) {
                    start += chart.gridStepChart;
                    continue;
                }
                paint.drawLine(chart.gridColor, chart.lineWidthChart, null, chart.leftVScaleWidth, Math.floor(hAxisY), chart.size.cx - chart.rightVScaleWidth, Math.floor(hAxisY));
                paint.drawLine(chart.scaleColor, chart.lineWidthChart, null, chart.leftVScaleWidth - 8, Math.floor(hAxisY), chart.leftVScaleWidth, Math.floor(hAxisY));
                paint.drawLine(chart.scaleColor, chart.lineWidthChart, null, chart.size.cx - chart.rightVScaleWidth, Math.floor(hAxisY), chart.size.cx - chart.rightVScaleWidth + 8, Math.floor(hAxisY));
                let drawText = (start / chart.magnitude).toFixed(chart.volDigit);
                let tSize = paint.textSize(drawText, chart.font);
                if (chart.vScaleTextColor != "none") {
                    paint.drawText(drawText, chart.vScaleTextColor, chart.font, chart.size.cx - chart.rightVScaleWidth + 10, Math.floor(hAxisY) - tSize.cy / 2);
                    paint.drawText(drawText, chart.vScaleTextColor, chart.font, chart.leftVScaleWidth - tSize.cx - 10, Math.floor(hAxisY) - tSize.cy / 2);
                }
                else {
                    paint.drawText(drawText, chart.textColor, chart.font, chart.size.cx - chart.rightVScaleWidth + 10, Math.floor(hAxisY) - tSize.cy / 2);
                    paint.drawText(drawText, chart.textColor, chart.font, chart.leftVScaleWidth - tSize.cx - 10, Math.floor(hAxisY) - tSize.cy / 2);
                }
            }
            start += chart.gridStepChart;
        }
    }
    if (indDivHeight > 0) {
        topPoint = new FCPoint(0, candleDivHeight + volDivHeight + 10);
        bottomPoint = new FCPoint(0, candleDivHeight + volDivHeight + indDivHeight - 10);
        let indMax = getChartValue(chart, topPoint);
        let indMin = getChartValue(chart, bottomPoint);
        chartGridScale(chart, indMin, indMax, (indDivHeight - chart.indPaddingTop - chart.indPaddingBottom) / 2, chart.vScaleDistance, chart.vScaleDistance / 2, Math.floor((indDivHeight - chart.indPaddingTop - chart.indPaddingBottom) / chart.vScaleDistance));
        if (chart.gridStepChart > 0) {
            let start = 0;
            if (indMin >= 0) {
                while (start + chart.gridStepChart < indMin) {
                    start += chart.gridStepChart;
                }
            }
            else {
                while (start - chart.gridStepChart > indMin) {
                    start -= chart.gridStepChart;
                }
            }
            while (start <= indMax) {
                if (start > indMin) {
                    let hAxisY = getChartY(chart, 2, start);
                    if (hAxisY < candleDivHeight + volDivHeight || hAxisY > candleDivHeight + volDivHeight + indDivHeight) {
                        start += chart.gridStepChart;
                        continue;
                    }
                    paint.drawLine(chart.gridColor, chart.lineWidthChart, null, chart.leftVScaleWidth, Math.floor(hAxisY), chart.size.cx - chart.rightVScaleWidth, Math.floor(hAxisY));
                    paint.drawLine(chart.scaleColor, chart.lineWidthChart, null, chart.leftVScaleWidth - 8, Math.floor(hAxisY), chart.leftVScaleWidth, Math.floor(hAxisY));
                    paint.drawLine(chart.scaleColor, chart.lineWidthChart, null, chart.size.cx - chart.rightVScaleWidth, Math.floor(hAxisY), chart.size.cx - chart.rightVScaleWidth + 8, Math.floor(hAxisY));
                    let drawText = start.toFixed(chart.indDigit);
                    let tSize = paint.textSize(drawText, chart.font);
                    if (chart.vScaleTextColor != "none") {
                        paint.drawText(drawText, chart.vScaleTextColor, chart.font, chart.size.cx - chart.rightVScaleWidth + 10, Math.floor(hAxisY) - tSize.cy / 2);
                        paint.drawText(drawText, chart.vScaleTextColor, chart.font, chart.leftVScaleWidth - tSize.cx - 10, Math.floor(hAxisY) - tSize.cy / 2);
                    }
                    else {
                        paint.drawText(drawText, chart.textColor, chart.font, chart.size.cx - chart.rightVScaleWidth + 10, Math.floor(hAxisY) - tSize.cy / 2);
                        paint.drawText(drawText, chart.textColor, chart.font, chart.leftVScaleWidth - tSize.cx - 10, Math.floor(hAxisY) - tSize.cy / 2);
                    }
                }
                start += chart.gridStepChart;
            }
        }
    }
    if (indDivHeight2 > 0) {
        topPoint = new FCPoint(0, candleDivHeight + volDivHeight + indDivHeight + 10);
        bottomPoint = new FCPoint(0, candleDivHeight + volDivHeight + indDivHeight + indDivHeight2 - 10);
        let indMax2 = getChartValue(chart, topPoint);
        let indMin2 = getChartValue(chart, bottomPoint);
        chartGridScale(chart, indMin2, indMax2, (indDivHeight2 - chart.indPaddingTop2 - chart.indPaddingBottom2) / 2, chart.vScaleDistance, chart.vScaleDistance / 2, Math.floor((indDivHeight2 - chart.indPaddingTop2 - chart.indPaddingBottom2) / chart.vScaleDistance));
        if (chart.gridStepChart > 0) {
            let start = 0;
            if (indMin2 >= 0) {
                while (start + chart.gridStepChart < indMin2) {
                    start += chart.gridStepChart;
                }
            }
            else {
                while (start - chart.gridStepChart > indMin2) {
                    start -= chart.gridStepChart;
                }
            }
            while (start <= indMax2) {
                if (start > indMin2) {
                    let hAxisY = getChartY(chart, 3, start);
                    if (hAxisY < candleDivHeight + volDivHeight + indDivHeight || hAxisY > candleDivHeight + volDivHeight + indDivHeight + indDivHeight2) {
                        start += chart.gridStepChart;
                        continue;
                    }
                    paint.drawLine(chart.gridColor, chart.lineWidthChart, null, chart.leftVScaleWidth, Math.floor(hAxisY), chart.size.cx - chart.rightVScaleWidth, Math.floor(hAxisY));
                    paint.drawLine(chart.scaleColor, chart.lineWidthChart, null, chart.leftVScaleWidth - 8, Math.floor(hAxisY), chart.leftVScaleWidth, Math.floor(hAxisY));
                    paint.drawLine(chart.scaleColor, chart.lineWidthChart, null, chart.size.cx - chart.rightVScaleWidth, Math.floor(hAxisY), chart.size.cx - chart.rightVScaleWidth + 8, Math.floor(hAxisY));
                    let drawText = start.toFixed(chart.indDigit);
                    let tSize = paint.textSize(drawText, chart.font);
                    if (chart.vScaleTextColor != "none") {
                        paint.drawText(drawText, chart.vScaleTextColor, chart.font, chart.size.cx - chart.rightVScaleWidth + 10, Math.floor(hAxisY) - tSize.cy / 2);
                        paint.drawText(drawText, chart.vScaleTextColor, chart.font, chart.leftVScaleWidth - tSize.cx - 10, Math.floor(hAxisY) - tSize.cy / 2);
                    }
                    else {
                        paint.drawText(drawText, chart.textColor, chart.font, chart.size.cx - chart.rightVScaleWidth + 10, Math.floor(hAxisY) - tSize.cy / 2);
                        paint.drawText(drawText, chart.textColor, chart.font, chart.leftVScaleWidth - tSize.cx - 10, Math.floor(hAxisY) - tSize.cy / 2);
                    }
                }
                start += chart.gridStepChart;
            }
        }
    }
    if (chart.onPaintChartHScale) {
        chart.onPaintChartHScale(chart, paint, clipRect);
    }
    else if (paint.onPaintChartHScale) {
        paint.onPaintChartHScale(chart, paint, clipRect);
    }
    else {
        if (chart.data && chart.data.length > 0 && chart.hScaleHeight > 0) {
            let dLeft = chart.leftVScaleWidth + 10;
            for (let i = chart.firstVisibleIndex; i <= chart.lastVisibleIndex; i++) {
                let date = new Date();
                date.setTime(chart.data[i].date);
                let xText = "";
                if (chart.hScaleFormat.length > 0) {
                    xText = dateFormat(chart.hScaleFormat, date);
                }
                else {
                    if (chart.cycle == "day") {
                        xText = dateFormat("YYYY-mm-dd", date);
                    }
                    else if (chart.cycle == "minute") {
                        xText = dateFormat("HH:MM", date);
                    }
                    else if (chart.cycle == "trend") {
                        xText = dateFormat("HH:MM", date);
                    }
                    else if (chart.cycle == "second") {
                        xText = dateFormat("HH:MM:SS", date);
                    }
                    else if (chart.cycle == "tick") {
                        xText = (i + 1).toString();
                    }
                }
                let tSize = paint.textSize(xText, chart.font);
                let x = getChartX(chart, i);
                let dx = x - tSize.cx / 2;
                if (dx > dLeft && dx < chart.size.cx - chart.rightVScaleWidth - 10) {
                    paint.drawLine(chart.scaleColor, chart.lineWidthChart, null, x, chart.size.cy - chart.hScaleHeight, x, chart.size.cy - chart.hScaleHeight + 8);
                    if (chart.hScaleTextColor != "none") {
                        paint.drawText(xText, chart.hScaleTextColor, chart.font, dx, chart.size.cy - chart.hScaleHeight + 8 - tSize.cy / 2 + 7);
                    }
                    else {
                        paint.drawText(xText, chart.textColor, chart.font, dx, chart.size.cy - chart.hScaleHeight + 8 - tSize.cy / 2 + 7);
                    }
                    i = i + Math.floor((tSize.cx + chart.hScaleTextDistance) / chart.hScalePixel) + 1;
                }
            }
        }
    }
}
/*
* 绘制十字线
* chart:图表
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawChartCrossLine(chart, paint, clipRect) {
    if (!chart.data || chart.data.length == 0) {
        return;
    }
    let candleDivHeight = getCandleDivHeight(chart);
    let volDivHeight = getVolDivHeight(chart);
    let indDivHeight = getIndDivHeight(chart);
    let indDivHeight2 = getIndDivHeight2(chart);
    let crossLineIndex = chart.crossStopIndex;
    if (crossLineIndex == -1 || !chart.showCrossLine) {
        if (chart.lastValidIndex != -1) {
            crossLineIndex = chart.lastValidIndex;
        }
        else {
            crossLineIndex = chart.lastVisibleIndex;
        }
    }
    if (crossLineIndex == -1) {
        return;
    }
    let str = "A" + crossLineIndex;
    if (str == "ANaN") {
        crossLineIndex = chart.lastVisibleIndex;
    }
    if (volDivHeight > 0) {
        let drawTitles = new Array();
        let drawColors = new Array();
        drawTitles.push("VOL " + (chart.data[crossLineIndex].volume / chart.magnitude).toFixed(chart.volDigit));
        drawColors.push(chart.textColor);
        if (chart.shapes.length > 0) {
            for (let i = 0; i < chart.shapes.length; i++) {
                let shape = chart.shapes[i];
                if (shape.divIndex == 1) {
                    if (shape.title.length > 0) {
                        if (shape.shapeType == "bar" && shape.style == "2color") {
                            drawTitles.push(shape.title + " " + shape.datas[crossLineIndex].toFixed(chart.volDigit));
                            drawColors.push(shape.color2);
                        }
                        else {
                            if (shape.shapeType != "text") {
                                drawTitles.push(shape.title + " " + shape.datas[crossLineIndex].toFixed(chart.volDigit));
                                drawColors.push(shape.color);
                                if (shape.datas2.length > 0) {
                                    drawTitles.push(shape.title2 + " " + shape.datas2[crossLineIndex].toFixed(chart.volDigit));
                                    drawColors.push(shape.color2);
                                }
                            }
                        }
                    }
                }
            }
        }
        let iLeft = chart.leftVScaleWidth + 5;
        for (let i = 0; i < drawTitles.length; i++) {
            let tSize = paint.textSize(drawTitles[i], chart.font);
            paint.drawText(drawTitles[i], drawColors[i], chart.font, iLeft, candleDivHeight + 5);
            iLeft += tSize.cx + 5;
        }
    }
    //上面显示数据  高开低收
    if (chart.cycle == "trend") {
        let drawTitles = new Array();
        let drawColors = new Array();
        if (chart.text && chart.text.length > 0) {
            drawTitles.push(chart.text);
            drawColors.push(chart.textColor);
        }
        if (chart.shapes.length > 0) {
            for (let i = 0; i < chart.shapes.length; i++) {
                let shape = chart.shapes[i];
                if (shape.divIndex == 0) {
                    if (shape.title.length > 0) {
                        if (shape.shapeType == "bar" && shape.style == "2color") {
                            drawTitles.push(shape.title + " " + shape.datas[crossLineIndex].toFixed(chart.candleDigit));
                            drawColors.push(shape.color2);
                        }
                        else {
                            if (shape.shapeType != "text") {
                                drawTitles.push(shape.title + " " + shape.datas[crossLineIndex].toFixed(chart.candleDigit));
                                drawColors.push(shape.color);
                                if (shape.datas2.length > 0) {
                                    drawTitles.push(shape.title2 + " " + shape.datas2[crossLineIndex].toFixed(chart.candleDigit));
                                    drawColors.push(shape.color2);
                                }
                            }
                        }
                    }
                }
            }
        }
        let iLeft = chart.leftVScaleWidth + 5;
        for (let i = 0; i < drawTitles.length; i++) {
            let tSize = paint.textSize(drawTitles[i], chart.font);
            paint.drawText(drawTitles[i], drawColors[i], chart.font, iLeft, 5);
            iLeft += tSize.cx + 5;
        }
    }
    else {
        let drawTitles = new Array();
        let drawColors = new Array();
        if (chart.text && chart.text.length > 0) {
            drawTitles.push(chart.text);
            drawColors.push(chart.textColor);
        }
        if (chart.mainIndicator == "MA") {
            if (chart.ma5 && chart.ma5.length > 0) {
                drawTitles.push("MA5 " + chart.ma5[crossLineIndex].toFixed(chart.candleDigit));
            }
            else {
                drawTitles.push("MA5");
            }
            drawColors.push(chart.indicatorColors[0]);
            if (chart.ma10 && chart.ma10.length > 0) {
                drawTitles.push("MA10 " + chart.ma10[crossLineIndex].toFixed(chart.candleDigit));
            }
            else {
                drawTitles.push("MA10");
            }
            drawColors.push(chart.indicatorColors[1]);
            if (chart.ma20 && chart.ma20.length > 0) {
                drawTitles.push("MA20 " + chart.ma20[crossLineIndex].toFixed(chart.candleDigit));
            }
            else {
                drawTitles.push("MA20");
            }
            drawColors.push(chart.indicatorColors[2]);
            if (chart.ma30 && chart.ma30.length > 0) {
                drawTitles.push("MA30 " + chart.ma30[crossLineIndex].toFixed(chart.candleDigit));
            }
            else {
                drawTitles.push("MA30");
            }
            drawColors.push(chart.indicatorColors[5]);
            if (chart.ma120 && chart.ma120.length > 0) {
                drawTitles.push("MA120 " + chart.ma120[crossLineIndex].toFixed(chart.candleDigit));
            }
            else {
                drawTitles.push("MA120");
            }
            drawColors.push(chart.indicatorColors[4]);
            if (chart.ma250 && chart.ma250.length > 0) {
                drawTitles.push("MA250 " + chart.ma250[crossLineIndex].toFixed(chart.candleDigit));
            }
            else {
                drawTitles.push("MA250");
            }
            drawColors.push(chart.indicatorColors[3]);
        }
        else if (chart.mainIndicator == "BOLL") {
            if (chart.bollMid && chart.bollMid.length > 0) {
                drawTitles.push("MID " + chart.bollMid[crossLineIndex].toFixed(chart.candleDigit));
            }
            else {
                drawTitles.push("MID");
            }
            drawColors.push(chart.indicatorColors[0]);
            if (chart.bollUp && chart.bollUp.length > 0) {
                drawTitles.push("UP " + chart.bollUp[crossLineIndex].toFixed(chart.candleDigit));
            }
            else {
                drawTitles.push("UP");
            }
            drawColors.push(chart.indicatorColors[1]);
            if (chart.bollDown && chart.bollDown.length > 0) {
                drawTitles.push("LOW " + chart.bollDown[crossLineIndex].toFixed(chart.candleDigit));
            }
            else {
                drawTitles.push("LOW");
            }
            drawColors.push(chart.indicatorColors[2]);
        }
        if (chart.shapes.length > 0) {
            for (let i = 0; i < chart.shapes.length; i++) {
                let shape = chart.shapes[i];
                if (shape.divIndex == 0) {
                    if (shape.title.length > 0) {
                        if (shape.shapeType == "bar" && shape.style == "2color") {
                            drawTitles.push(shape.title + " " + shape.datas[crossLineIndex].toFixed(chart.candleDigit));
                            drawColors.push(shape.color2);
                        }
                        else {
                            if (shape.shapeType != "text") {
                                drawTitles.push(shape.title + " " + shape.datas[crossLineIndex].toFixed(chart.candleDigit));
                                drawColors.push(shape.color);
                                if (shape.datas2.length > 0) {
                                    drawTitles.push(shape.title2 + " " + shape.datas2[crossLineIndex].toFixed(chart.candleDigit));
                                    drawColors.push(shape.color2);
                                }
                            }
                        }
                    }
                }
            }
        }
        let iLeft = chart.leftVScaleWidth + 5;
        for (let i = 0; i < drawTitles.length; i++) {
            let tSize = paint.textSize(drawTitles[i], chart.font);
            paint.drawText(drawTitles[i], drawColors[i], chart.font, iLeft, 5);
            iLeft += tSize.cx + 5;
        }
    }
    if (indDivHeight > 0) {
        let drawTitles = new Array();
        let drawColors = new Array();
        if (chart.showIndicator == "MACD") {
            if (chart.alldifarr && chart.alldifarr.length > 0) {
                drawTitles.push("DIF " + chart.alldifarr[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("DIF");
            }
            drawColors.push(chart.indicatorColors[0]);
            if (chart.alldeaarr && chart.alldeaarr.length > 0) {
                drawTitles.push("DEA " + chart.alldeaarr[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("DEA");
            }
            drawColors.push(chart.indicatorColors[1]);
            if (chart.allmacdarr && chart.allmacdarr.length > 0) {
                drawTitles.push("MACD " + chart.allmacdarr[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("MACD");
            }
            drawColors.push(chart.indicatorColors[4]);
        }
        else if (chart.showIndicator == "KDJ") {
            if (chart.kdjK && chart.kdjK.length > 0) {
                drawTitles.push("K " + chart.kdjK[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("K");
            }
            drawColors.push(chart.indicatorColors[0]);
            if (chart.kdjD && chart.kdjD.length > 0) {
                drawTitles.push("D " + chart.kdjD[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("D");
            }
            drawColors.push(chart.indicatorColors[1]);
            if (chart.kdjJ && chart.kdjJ.length > 0) {
                drawTitles.push("J " + chart.kdjJ[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("J");
            }
            drawColors.push(chart.indicatorColors[2]);
        }
        else if (chart.showIndicator == "RSI") {
            if (chart.rsi1 && chart.rsi1.length > 0) {
                drawTitles.push("RSI6 " + chart.rsi1[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("RSI6");
            }
            drawColors.push(chart.indicatorColors[5]);
            if (chart.rsi2 && chart.rsi2.length > 0) {
                drawTitles.push("RSI12 " + chart.rsi2[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("RSI12");
            }
            drawColors.push(chart.indicatorColors[1]);
            if (chart.rsi3 && chart.rsi3.length > 0) {
                drawTitles.push("RSI24 " + chart.rsi3[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("RSI24");
            }
            drawColors.push(chart.indicatorColors[2]);
        }
        else if (chart.showIndicator == "BIAS") {
            if (chart.bias1 && chart.bias1.length > 0) {
                drawTitles.push("BIAS6 " + chart.bias1[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("BIAS6");
            }
            drawColors.push(chart.indicatorColors[5]);
            if (chart.bias2 && chart.bias2.length > 0) {
                drawTitles.push("BIAS12 " + chart.bias2[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("BIAS12");
            }
            drawColors.push(chart.indicatorColors[1]);
            if (chart.bias3 && chart.bias3.length > 0) {
                drawTitles.push("BIAS24 " + chart.bias3[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("BIAS24");
            }
            drawColors.push(chart.indicatorColors[2]);
        }
        else if (chart.showIndicator == "ROC") {
            if (chart.roc && chart.roc.length > 0) {
                drawTitles.push("ROC " + chart.roc[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("ROC");
            }
            drawColors.push(chart.indicatorColors[0]);
            if (chart.rocMa && chart.rocMa.length > 0) {
                drawTitles.push("ROCMA " + chart.rocMa[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("ROCMA");
            }
            drawColors.push(chart.indicatorColors[1]);
        }
        else if (chart.showIndicator == "WR") {
            if (chart.wr1 && chart.wr1.length > 0) {
                drawTitles.push("WR5 " + chart.wr1[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("WR5");
            }
            drawColors.push(chart.indicatorColors[0]);
            if (chart.wr2 && chart.wr2.length > 0) {
                drawTitles.push("WR10 " + chart.wr2[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("WR10");
            }
            drawColors.push(chart.indicatorColors[1]);
        }
        else if (chart.showIndicator == "CCI") {
            if (chart.cci && chart.cci.length > 0) {
                drawTitles.push("CCI " + chart.cci[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("CCI");
            }
            drawColors.push(chart.indicatorColors[0]);
        }
        else if (chart.showIndicator == "BBI") {
            if (chart.bbi && chart.bbi.length > 0) {
                drawTitles.push("BBI " + chart.bbi[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("BBI");
            }
            drawColors.push(chart.indicatorColors[0]);
        }
        else if (chart.showIndicator == "TRIX") {
            if (chart.trix && chart.trix.length > 0) {
                drawTitles.push("TRIX " + chart.trix[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("TRIX");
            }
            drawColors.push(chart.indicatorColors[0]);
            if (chart.trixMa && chart.trixMa.length > 0) {
                drawTitles.push("TRIXMA " + chart.trixMa[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("TRIXMA");
            }
            drawColors.push(chart.indicatorColors[1]);
        }
        else if (chart.showIndicator == "DMA") {
            if (chart.dma1 && chart.dma1.length > 0) {
                drawTitles.push("MA10 " + chart.dma1[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("MA10");
            }
            drawColors.push(chart.indicatorColors[0]);
            if (chart.dma2 && chart.dma2.length > 0) {
                drawTitles.push("MA50 " + chart.dma2[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("MA50");
            }
            drawColors.push(chart.indicatorColors[1]);
        }
        if (chart.shapes.length > 0) {
            for (let i = 0; i < chart.shapes.length; i++) {
                let shape = chart.shapes[i];
                if (shape.divIndex == 2) {
                    if (shape.title.length > 0) {
                        if (shape.shapeType == "bar" && shape.style == "2color") {
                            drawTitles.push(shape.title + " " + shape.datas[crossLineIndex].toFixed(chart.indDigit));
                            drawColors.push(shape.color2);
                        }
                        else {
                            if (shape.shapeType != "text") {
                                drawTitles.push(shape.title + " " + shape.datas[crossLineIndex].toFixed(chart.indDigit));
                                drawColors.push(shape.color);
                                if (shape.datas2.length > 0) {
                                    drawTitles.push(shape.title2 + " " + shape.datas2[crossLineIndex].toFixed(chart.indDigit));
                                    drawColors.push(shape.color2);
                                }
                            }
                        }
                    }
                }
            }
        }
        let iLeft = chart.leftVScaleWidth + 5;
        for (let i = 0; i < drawTitles.length; i++) {
            let tSize = paint.textSize(drawTitles[i], chart.font);
            paint.drawText(drawTitles[i], drawColors[i], chart.font, iLeft, candleDivHeight + volDivHeight + 5);
            iLeft += tSize.cx + 5;
        }
    }
    if (indDivHeight2 > 0) {
        let drawTitles = new Array();
        let drawColors = new Array();
        if (chart.showIndicator2 == "MACD") {
            if (chart.alldifarr && chart.alldifarr.length > 0) {
                drawTitles.push("DIF " + chart.alldifarr[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("DIF");
            }
            drawColors.push(chart.indicatorColors[0]);
            if (chart.alldeaarr && chart.alldeaarr.length > 0) {
                drawTitles.push("DEA " + chart.alldeaarr[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("DEA");
            }
            drawColors.push(chart.indicatorColors[1]);
            if (chart.allmacdarr && chart.allmacdarr.length > 0) {
                drawTitles.push("MACD " + chart.allmacdarr[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("MACD");
            }
            drawColors.push(chart.indicatorColors[4]);
        }
        else if (chart.showIndicator2 == "KDJ") {
            if (chart.kdjK && chart.kdjK.length > 0) {
                drawTitles.push("K " + chart.kdjK[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("K");
            }
            drawColors.push(chart.indicatorColors[0]);
            if (chart.kdjD && chart.kdjD.length > 0) {
                drawTitles.push("D " + chart.kdjD[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("D");
            }
            drawColors.push(chart.indicatorColors[1]);
            if (chart.kdjJ && chart.kdjJ.length > 0) {
                drawTitles.push("J " + chart.kdjJ[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("J");
            }
            drawColors.push(chart.indicatorColors[2]);
        }
        else if (chart.showIndicator2 == "RSI") {
            if (chart.rsi1 && chart.rsi1.length > 0) {
                drawTitles.push("RSI6 " + chart.rsi1[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("RSI6");
            }
            drawColors.push(chart.indicatorColors[5]);
            if (chart.rsi2 && chart.rsi2.length > 0) {
                drawTitles.push("RSI12 " + chart.rsi2[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("RSI12");
            }
            drawColors.push(chart.indicatorColors[1]);
            if (chart.rsi3 && chart.rsi3.length > 0) {
                drawTitles.push("RSI24 " + chart.rsi3[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("RSI24");
            }
            drawColors.push(chart.indicatorColors[2]);
        }
        else if (chart.showIndicator2 == "BIAS") {
            if (chart.bias1 && chart.bias1.length > 0) {
                drawTitles.push("BIAS6 " + chart.bias1[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("BIAS6");
            }
            drawColors.push(chart.indicatorColors[5]);
            if (chart.bias2 && chart.bias2.length > 0) {
                drawTitles.push("BIAS12 " + chart.bias2[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("BIAS12");
            }
            drawColors.push(chart.indicatorColors[1]);
            if (chart.bias3 && chart.bias3.length > 0) {
                drawTitles.push("BIAS24 " + chart.bias3[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("BIAS24");
            }
            drawColors.push(chart.indicatorColors[2]);
        }
        else if (chart.showIndicator2 == "ROC") {
            if (chart.roc && chart.roc.length > 0) {
                drawTitles.push("ROC " + chart.roc[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("ROC");
            }
            drawColors.push(chart.indicatorColors[0]);
            if (chart.rocMa && chart.rocMa.length > 0) {
                drawTitles.push("ROCMA " + chart.rocMa[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("ROCMA");
            }
            drawColors.push(chart.indicatorColors[1]);
        }
        else if (chart.showIndicator2 == "WR") {
            if (chart.wr1 && chart.wr1.length > 0) {
                drawTitles.push("WR5 " + chart.wr1[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("WR5");
            }
            drawColors.push(chart.indicatorColors[0]);
            if (chart.wr2 && chart.wr2.length > 0) {
                drawTitles.push("WR10 " + chart.wr2[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("WR10");
            }
            drawColors.push(chart.indicatorColors[1]);
        }
        else if (chart.showIndicator2 == "CCI") {
            if (chart.cci && chart.cci.length > 0) {
                drawTitles.push("CCI " + chart.cci[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("CCI");
            }
            drawColors.push(chart.indicatorColors[0]);
        }
        else if (chart.showIndicator2 == "BBI") {
            if (chart.bbi && chart.bbi.length > 0) {
                drawTitles.push("BBI " + chart.bbi[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("BBI");
            }
            drawColors.push(chart.indicatorColors[0]);
        }
        else if (chart.showIndicator2 == "TRIX") {
            if (chart.trix && chart.trix.length > 0) {
                drawTitles.push("TRIX " + chart.trix[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("TRIX");
            }
            drawColors.push(chart.indicatorColors[0]);
            if (chart.trixMa && chart.trixMa.length > 0) {
                drawTitles.push("TRIXMA " + chart.trixMa[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("TRIXMA");
            }
            drawColors.push(chart.indicatorColors[1]);
        }
        else if (chart.showIndicator2 == "DMA") {
            if (chart.dma1 && chart.dma1.length > 0) {
                drawTitles.push("MA10 " + chart.dma1[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("MA10");
            }
            drawColors.push(chart.indicatorColors[0]);
            if (chart.dma2 && chart.dma2.length > 0) {
                drawTitles.push("MA50 " + chart.dma2[crossLineIndex].toFixed(chart.indDigit));
            }
            else {
                drawTitles.push("MA50");
            }
            drawColors.push(chart.indicatorColors[1]);
        }
        if (chart.shapes.length > 0) {
            for (let i = 0; i < chart.shapes.length; i++) {
                let shape = chart.shapes[i];
                if (shape.divIndex == 3) {
                    if (shape.title.length > 0) {
                        if (shape.shapeType == "bar" && shape.style == "2color") {
                            drawTitles.push(shape.title + " " + shape.datas[crossLineIndex].toFixed(chart.indDigit2));
                            drawColors.push(shape.color2);
                        }
                        else {
                            if (shape.shapeType != "text") {
                                drawTitles.push(shape.title + " " + shape.datas[crossLineIndex].toFixed(chart.indDigit2));
                                drawColors.push(shape.color);
                                if (shape.datas2.length > 0) {
                                    drawTitles.push(shape.title2 + " " + shape.datas2[crossLineIndex].toFixed(chart.indDigit2));
                                    drawColors.push(shape.color2);
                                }
                            }
                        }
                    }
                }
            }
        }
        if (drawTitles.length > 0) {
            let iLeft = chart.leftVScaleWidth + 5;
            for (let i = 0; i < drawTitles.length; i++) {
                let tSize = paint.textSize(drawTitles[i], chart.font);
                paint.drawText(drawTitles[i], drawColors[i], chart.font, iLeft, candleDivHeight + volDivHeight + indDivHeight + 5);
                iLeft += tSize.cx + 5;
            }
        }
    }
    if (chart.showCrossLine) {
        let rightText = "";
        if (chart.touchPosition.y < candleDivHeight) {
            rightText = getChartValue(chart, chart.touchPosition).toFixed(chart.candleDigit);
        }
        else if (chart.touchPosition.y > candleDivHeight && chart.touchPosition.y < candleDivHeight + volDivHeight) {
            rightText = (getChartValue(chart, chart.touchPosition) / chart.magnitude).toFixed(chart.volDigit);
        }
        else if (chart.touchPosition.y > candleDivHeight + volDivHeight && chart.touchPosition.y < candleDivHeight + volDivHeight + indDivHeight) {
            rightText = getChartValue(chart, chart.touchPosition).toFixed(chart.indDigit);
        }
        else if (chart.touchPosition.y > candleDivHeight + volDivHeight + indDivHeight && chart.touchPosition.y < candleDivHeight + volDivHeight + indDivHeight + indDivHeight2) {
            rightText = getChartValue(chart, chart.touchPosition).toFixed(chart.indDigit2);
        }
        let drawY = chart.touchPosition.y;
        if (drawY > chart.size.cy - chart.hScaleHeight) {
            drawY = chart.size.cy - chart.hScaleHeight;
        }
        let tSize = paint.textSize(rightText, chart.font);
        if (chart.leftVScaleWidth > 0) {
            paint.fillRect(chart.crossTipColor, chart.leftVScaleWidth - tSize.cx, drawY - tSize.cy / 2 - 4, chart.leftVScaleWidth, drawY + tSize.cy / 2 + 3);
            paint.drawText(rightText, chart.textColor, chart.font, chart.leftVScaleWidth - tSize.cx, drawY - tSize.cy / 2);
        }
        if (chart.rightVScaleWidth > 0) {
            paint.fillRect(chart.crossTipColor, chart.size.cx - chart.rightVScaleWidth, drawY - tSize.cy / 2 - 4, chart.size.cx - chart.rightVScaleWidth + tSize.cx, drawY + tSize.cy / 2 + 3);
            paint.drawText(rightText, chart.textColor, chart.font, chart.size.cx - chart.rightVScaleWidth, drawY - tSize.cy / 2);
        }
        //绘制十字线
        let drawX = getChartX(chart, chart.crossStopIndex);
        if (chart.targetOldX == 0 && chart.targetOldX2 == 0) {
            drawX = chart.touchPosition.x;
        }
        if (drawX < chart.leftVScaleWidth) {
            drawX = chart.leftVScaleWidth;
        }
        if (drawX > chart.size.cx - chart.rightVScaleWidth) {
            drawX = chart.size.cx - chart.rightVScaleWidth;
        }
        if (!chart.sPlot && chart.selectShape == "") {
            paint.drawLine(chart.crossLineColor, chart.lineWidthChart, null, chart.leftVScaleWidth, drawY, chart.size.cx - chart.rightVScaleWidth, drawY);
            paint.drawLine(chart.crossLineColor, chart.lineWidthChart, null, drawX, 0, drawX, chart.size.cy - chart.hScaleHeight);
        }
        let str = "A" + chart.crossStopIndex;
        if (chart.crossStopIndex != -1 && chart.crossStopIndex < chart.data.length && str != "ANaN") {
            let date = new Date();
            date.setTime(chart.data[chart.crossStopIndex].date);
            let xText = "";
            if (chart.cycle == "day") {
                xText = dateFormat("YYYY-mm-dd", date);
            }
            else if (chart.cycle == "minute") {
                xText = dateFormat("HH:MM", date);
            }
            else if (chart.cycle == "trend") {
                xText = dateFormat("HH:MM", date);
            }
            else if (chart.cycle == "second") {
                xText = dateFormat("HH:MM:SS", date);
            }
            else if (chart.cycle == "tick") {
                xText = (chart.crossStopIndex + 1).toString();
            }
            if (chart.hScaleFormat.length > 0) {
                xText = dateFormat(chart.hScaleFormat, date);
            }
            let xSize = paint.textSize(xText, chart.font);
            paint.fillRect(chart.crossTipColor, drawX - xSize.cx / 2 - 2, candleDivHeight + volDivHeight + indDivHeight, drawX + xSize.cx / 2 + 2, candleDivHeight + volDivHeight + indDivHeight + xSize.cy + 6);
            paint.drawText(xText, chart.textColor, chart.font, drawX - xSize.cx / 2, candleDivHeight + volDivHeight + indDivHeight + 3);
        }
    }
}
/*
* 计算最大最小值
* chart:图表
*/
function calculateChartMaxMin(chart) {
    chart.candleMax = 0;
    chart.candleMin = 0;
    chart.volMax = 0;
    chart.volMin = 0;
    chart.indMin = 0;
    chart.indMin = 0;
    let load1 = false;
    let load2 = false;
    let load3 = false;
    let load4 = false;
    let isTrend = chart.cycle == "trend";
    let firstOpen = chart.firstOpen;
    if (chart.data.length > 0) {
        let lastValidIndex = chart.lastVisibleIndex;
        if (chart.lastValidIndex != -1) {
            lastValidIndex = chart.lastValidIndex;
        }
        for (let i = chart.firstVisibleIndex; i <= lastValidIndex; i++) {
            if (i == chart.firstVisibleIndex) {
                if (isTrend) {
                    chart.candleMax = chart.data[i].close;
                    chart.candleMin = chart.data[i].close;
                    if (firstOpen == 0) {
                        firstOpen = chart.data[i].close;
                    }
                }
                else {
                    chart.candleMax = chart.data[i].high;
                    chart.candleMin = chart.data[i].low;
                }
                chart.volMax = chart.data[i].volume;
                load1 = true;
                load2 = true;
                if (chart.showIndicator == "MACD") {
                    chart.indMax = chart.alldifarr[i];
                    chart.indMin = chart.alldifarr[i];
                    load3 = true;
                }
                else if (chart.showIndicator == "KDJ") {
                    chart.indMax = chart.kdjK[i];
                    chart.indMin = chart.kdjK[i];
                    load3 = true;
                }
                else if (chart.showIndicator == "RSI") {
                    chart.indMax = chart.rsi1[i];
                    chart.indMin = chart.rsi1[i];
                    load3 = true;
                }
                else if (chart.showIndicator == "BIAS") {
                    chart.indMax = chart.bias1[i];
                    chart.indMin = chart.bias1[i];
                    load3 = true;
                }
                else if (chart.showIndicator == "ROC") {
                    chart.indMax = chart.roc[i];
                    chart.indMin = chart.roc[i];
                    load3 = true;
                }
                else if (chart.showIndicator == "WR") {
                    chart.indMax = chart.wr1[i];
                    chart.indMin = chart.wr1[i];
                    load3 = true;
                }
                else if (chart.showIndicator == "CCI") {
                    chart.indMax = chart.cci[i];
                    chart.indMin = chart.cci[i];
                    load3 = true;
                }
                else if (chart.showIndicator == "BBI") {
                    chart.indMax = chart.bbi[i];
                    chart.indMin = chart.bbi[i];
                    load3 = true;
                }
                else if (chart.showIndicator == "TRIX") {
                    chart.indMax = chart.trix[i];
                    chart.indMin = chart.trix[i];
                    load3 = true;
                }
                else if (chart.showIndicator == "DMA") {
                    chart.indMax = chart.dma1[i];
                    chart.indMin = chart.dma1[i];
                    load3 = true;
                }
                if (chart.showIndicator2 == "MACD") {
                    chart.indMax2 = chart.alldifarr[i];
                    chart.indMin2 = chart.alldifarr[i];
                    load4 = true;
                }
                else if (chart.showIndicator2 == "KDJ") {
                    chart.indMax2 = chart.kdjK[i];
                    chart.indMin2 = chart.kdjK[i];
                    load4 = true;
                }
                else if (chart.showIndicator2 == "RSI") {
                    chart.indMax2 = chart.rsi1[i];
                    chart.indMin2 = chart.rsi1[i];
                    load4 = true;
                }
                else if (chart.showIndicator2 == "BIAS") {
                    chart.indMax2 = chart.bias1[i];
                    chart.indMin2 = chart.bias1[i];
                    load4 = true;
                }
                else if (chart.showIndicator2 == "ROC") {
                    chart.indMax2 = chart.roc[i];
                    chart.indMin2 = chart.roc[i];
                    load4 = true;
                }
                else if (chart.showIndicator2 == "WR") {
                    chart.indMax2 = chart.wr1[i];
                    chart.indMin2 = chart.wr1[i];
                    load4 = true;
                }
                else if (chart.showIndicator2 == "CCI") {
                    chart.indMax2 = chart.cci[i];
                    chart.indMin2 = chart.cci[i];
                    load4 = true;
                }
                else if (chart.showIndicator2 == "BBI") {
                    chart.indMax2 = chart.bbi[i];
                    chart.indMin2 = chart.bbi[i];
                    load4 = true;
                }
                else if (chart.showIndicator2 == "TRIX") {
                    chart.indMax2 = chart.trix[i];
                    chart.indMin2 = chart.trix[i];
                    load4 = true;
                }
                else if (chart.showIndicator2 == "DMA") {
                    chart.indMax2 = chart.dma1[i];
                    chart.indMin2 = chart.dma1[i];
                    load4 = true;
                }
            }
            else {
                if (isTrend) {
                    if (chart.candleMax < chart.data[i].close) {
                        chart.candleMax = chart.data[i].close;
                    }
                    if (chart.candleMin > chart.data[i].close) {
                        chart.candleMin = chart.data[i].close;
                    }
                }
                else {
                    if (chart.candleMax < chart.data[i].high) {
                        chart.candleMax = chart.data[i].high;
                    }
                    if (chart.candleMin > chart.data[i].low) {
                        chart.candleMin = chart.data[i].low;
                    }
                }
                if (chart.volMax < chart.data[i].volume) {
                    chart.volMax = chart.data[i].volume;
                }
            }
            if (chart.showIndicator == "MACD") {
                if (chart.indMax < chart.alldifarr[i]) {
                    chart.indMax = chart.alldifarr[i];
                }
                if (chart.indMax < chart.alldeaarr[i]) {
                    chart.indMax = chart.alldeaarr[i];
                }
                if (chart.indMax < chart.allmacdarr[i]) {
                    chart.indMax = chart.allmacdarr[i];
                }
                if (chart.indMin > chart.alldifarr[i]) {
                    chart.indMin = chart.alldifarr[i];
                }
                if (chart.indMin > chart.alldeaarr[i]) {
                    chart.indMin = chart.alldeaarr[i];
                }
                if (chart.indMin > chart.allmacdarr[i]) {
                    chart.indMin = chart.allmacdarr[i];
                }
            }
            else if (chart.showIndicator == "KDJ") {
                if (chart.indMax < chart.kdjK[i]) {
                    chart.indMax = chart.kdjK[i];
                }
                if (chart.indMax < chart.kdjD[i]) {
                    chart.indMax = chart.kdjD[i];
                }
                if (chart.indMax < chart.kdjJ[i]) {
                    chart.indMax = chart.kdjJ[i];
                }
                if (chart.indMin > chart.kdjK[i]) {
                    chart.indMin = chart.kdjK[i];
                }
                if (chart.indMin > chart.kdjD[i]) {
                    chart.indMin = chart.kdjD[i];
                }
                if (chart.indMin > chart.kdjJ[i]) {
                    chart.indMin = chart.kdjJ[i];
                }
            }
            else if (chart.showIndicator == "RSI") {
                if (chart.indMax < chart.rsi1[i]) {
                    chart.indMax = chart.rsi1[i];
                }
                if (chart.indMax < chart.rsi2[i]) {
                    chart.indMax = chart.rsi2[i];
                }
                if (chart.indMax < chart.rsi3[i]) {
                    chart.indMax = chart.rsi3[i];
                }
                if (chart.indMin > chart.rsi1[i]) {
                    chart.indMin = chart.rsi1[i];
                }
                if (chart.indMin > chart.rsi2[i]) {
                    chart.indMin = chart.rsi2[i];
                }
                if (chart.indMin > chart.rsi3[i]) {
                    chart.indMin = chart.rsi3[i];
                }
            }
            else if (chart.showIndicator == "BIAS") {
                if (chart.indMax < chart.bias1[i]) {
                    chart.indMax = chart.bias1[i];
                }
                if (chart.indMax < chart.bias2[i]) {
                    chart.indMax = chart.bias2[i];
                }
                if (chart.indMax < chart.bias3[i]) {
                    chart.indMax = chart.bias3[i];
                }
                if (chart.indMin > chart.bias1[i]) {
                    chart.indMin = chart.bias1[i];
                }
                if (chart.indMin > chart.bias2[i]) {
                    chart.indMin = chart.bias2[i];
                }
                if (chart.indMin > chart.bias3[i]) {
                    chart.indMin = chart.bias3[i];
                }
            }
            else if (chart.showIndicator == "ROC") {
                if (chart.indMax < chart.roc[i]) {
                    chart.indMax = chart.roc[i];
                }
                if (chart.indMax < chart.rocMa[i]) {
                    chart.indMax = chart.rocMa[i];
                }
                if (chart.indMin > chart.roc[i]) {
                    chart.indMin = chart.roc[i];
                }
                if (chart.indMin > chart.rocMa[i]) {
                    chart.indMin = chart.rocMa[i];
                }
            }
            else if (chart.showIndicator == "WR") {
                if (chart.indMax < chart.wr1[i]) {
                    chart.indMax = chart.wr1[i];
                }
                if (chart.indMax < chart.wr2[i]) {
                    chart.indMax = chart.wr2[i];
                }
                if (chart.indMin > chart.wr1[i]) {
                    chart.indMin = chart.wr1[i];
                }
                if (chart.indMin > chart.wr2[i]) {
                    chart.indMin = chart.wr2[i];
                }
            }
            else if (chart.showIndicator == "CCI") {
                if (chart.indMax < chart.cci[i]) {
                    chart.indMax = chart.cci[i];
                }
                if (chart.indMin > chart.cci[i]) {
                    chart.indMin = chart.cci[i];
                }
            }
            else if (chart.showIndicator == "BBI") {
                if (chart.indMax < chart.bbi[i]) {
                    chart.indMax = chart.bbi[i];
                }
                if (chart.indMin > chart.bbi[i]) {
                    chart.indMin = chart.bbi[i];
                }
            }
            else if (chart.showIndicator == "TRIX") {
                if (chart.indMax < chart.trix[i]) {
                    chart.indMax = chart.trix[i];
                }
                if (chart.indMax < chart.trixMa[i]) {
                    chart.indMax = chart.trixMa[i];
                }
                if (chart.indMin > chart.trix[i]) {
                    chart.indMin = chart.trix[i];
                }
                if (chart.indMin > chart.trixMa[i]) {
                    chart.indMin = chart.trixMa[i];
                }
            }
            else if (chart.showIndicator == "DMA") {
                if (chart.indMax < chart.dma1[i]) {
                    chart.indMax = chart.dma1[i];
                }
                if (chart.indMax < chart.dma2[i]) {
                    chart.indMax = chart.dma2[i];
                }
                if (chart.indMin > chart.dma1[i]) {
                    chart.indMin = chart.dma1[i];
                }
                if (chart.indMin > chart.dma2[i]) {
                    chart.indMin = chart.dma2[i];
                }
            }
            if (chart.showIndicator2 == "MACD") {
                if (chart.indMax2 < chart.alldifarr[i]) {
                    chart.indMax2 = chart.alldifarr[i];
                }
                if (chart.indMax2 < chart.alldeaarr[i]) {
                    chart.indMax2 = chart.alldeaarr[i];
                }
                if (chart.indMax2 < chart.allmacdarr[i]) {
                    chart.indMax2 = chart.allmacdarr[i];
                }
                if (chart.indMin2 > chart.alldifarr[i]) {
                    chart.indMin2 = chart.alldifarr[i];
                }
                if (chart.indMin2 > chart.alldeaarr[i]) {
                    chart.indMin2 = chart.alldeaarr[i];
                }
                if (chart.indMin2 > chart.allmacdarr[i]) {
                    chart.indMin2 = chart.allmacdarr[i];
                }
            }
            else if (chart.showIndicator2 == "KDJ") {
                if (chart.indMax2 < chart.kdjK[i]) {
                    chart.indMax2 = chart.kdjK[i];
                }
                if (chart.indMax2 < chart.kdjD[i]) {
                    chart.indMax2 = chart.kdjD[i];
                }
                if (chart.indMax2 < chart.kdjJ[i]) {
                    chart.indMax2 = chart.kdjJ[i];
                }
                if (chart.indMin2 > chart.kdjK[i]) {
                    chart.indMin2 = chart.kdjK[i];
                }
                if (chart.indMin2 > chart.kdjD[i]) {
                    chart.indMin2 = chart.kdjD[i];
                }
                if (chart.indMin2 > chart.kdjJ[i]) {
                    chart.indMin2 = chart.kdjJ[i];
                }
            }
            else if (chart.showIndicator2 == "RSI") {
                if (chart.indMax2 < chart.rsi1[i]) {
                    chart.indMax2 = chart.rsi1[i];
                }
                if (chart.indMax2 < chart.rsi2[i]) {
                    chart.indMax2 = chart.rsi2[i];
                }
                if (chart.indMax2 < chart.rsi3[i]) {
                    chart.indMax2 = chart.rsi3[i];
                }
                if (chart.indMin2 > chart.rsi1[i]) {
                    chart.indMin2 = chart.rsi1[i];
                }
                if (chart.indMin2 > chart.rsi2[i]) {
                    chart.indMin2 = chart.rsi2[i];
                }
                if (chart.indMin2 > chart.rsi3[i]) {
                    chart.indMin2 = chart.rsi3[i];
                }
            }
            else if (chart.showIndicator2 == "BIAS") {
                if (chart.indMax2 < chart.bias1[i]) {
                    chart.indMax2 = chart.bias1[i];
                }
                if (chart.indMax2 < chart.bias2[i]) {
                    chart.indMax2 = chart.bias2[i];
                }
                if (chart.indMax2 < chart.bias3[i]) {
                    chart.indMax2 = chart.bias3[i];
                }
                if (chart.indMin2 > chart.bias1[i]) {
                    chart.indMin2 = chart.bias1[i];
                }
                if (chart.indMin2 > chart.bias2[i]) {
                    chart.indMin2 = chart.bias2[i];
                }
                if (chart.indMin2 > chart.bias3[i]) {
                    chart.indMin2 = chart.bias3[i];
                }
            }
            else if (chart.showIndicator2 == "ROC") {
                if (chart.indMax2 < chart.roc[i]) {
                    chart.indMax2 = chart.roc[i];
                }
                if (chart.indMax2 < chart.rocMa[i]) {
                    chart.indMax2 = chart.rocMa[i];
                }
                if (chart.indMin2 > chart.roc[i]) {
                    chart.indMin2 = chart.roc[i];
                }
                if (chart.indMin2 > chart.rocMa[i]) {
                    chart.indMin2 = chart.rocMa[i];
                }
            }
            else if (chart.showIndicator2 == "WR") {
                if (chart.indMax2 < chart.wr1[i]) {
                    chart.indMax2 = chart.wr1[i];
                }
                if (chart.indMax2 < chart.wr2[i]) {
                    chart.indMax2 = chart.wr2[i];
                }
                if (chart.indMin2 > chart.wr1[i]) {
                    chart.indMin2 = chart.wr1[i];
                }
                if (chart.indMin2 > chart.wr2[i]) {
                    chart.indMin2 = chart.wr2[i];
                }
            }
            else if (chart.showIndicator2 == "CCI") {
                if (chart.indMax2 < chart.cci[i]) {
                    chart.indMax2 = chart.cci[i];
                }
                if (chart.indMin2 > chart.cci[i]) {
                    chart.indMin2 = chart.cci[i];
                }
            }
            else if (chart.showIndicator2 == "BBI") {
                if (chart.indMax2 < chart.bbi[i]) {
                    chart.indMax2 = chart.bbi[i];
                }
                if (chart.indMin2 > chart.bbi[i]) {
                    chart.indMin2 = chart.bbi[i];
                }
            }
            else if (chart.showIndicator2 == "TRIX") {
                if (chart.indMax2 < chart.trix[i]) {
                    chart.indMax2 = chart.trix[i];
                }
                if (chart.indMax2 < chart.trixMa[i]) {
                    chart.indMax2 = chart.trixMa[i];
                }
                if (chart.indMin2 > chart.trix[i]) {
                    chart.indMin2 = chart.trix[i];
                }
                if (chart.indMin2 > chart.trixMa[i]) {
                    chart.indMin2 = chart.trixMa[i];
                }
            }
            else if (chart.showIndicator2 == "DMA") {
                if (chart.indMax2 < chart.dma1[i]) {
                    chart.indMax2 = chart.dma1[i];
                }
                if (chart.indMax2 < chart.dma2[i]) {
                    chart.indMax2 = chart.dma2[i];
                }
                if (chart.indMin2 > chart.dma1[i]) {
                    chart.indMin2 = chart.dma1[i];
                }
                if (chart.indMin2 > chart.dma2[i]) {
                    chart.indMin2 = chart.dma2[i];
                }
            }
        }
    }
    if (chart.shapes.length > 0) {
        let lastValidIndex = chart.lastVisibleIndex;
        if (chart.lastValidIndex != -1) {
            lastValidIndex = chart.lastValidIndex;
        }
        for (let s = 0; s < chart.shapes.length; s++) {
            let shape = chart.shapes[s];
            if (shape.datas.length > 0) {
                for (let i = chart.firstVisibleIndex; i <= lastValidIndex; i++) {
                    if (shape.divIndex == 0) {
                        if (!load1 && i == chart.firstVisibleIndex) {
                            if (shape.leftOrRight) {
                                chart.candleMax = shape.datas[i];
                                chart.candleMin = shape.datas[i];
                            }
                            else {
                                chart.candleMaxRight = shape.datas[i];
                                chart.candleMinRight = shape.datas[i];
                            }
                            load1 = true;
                        }
                        else {
                            if (shape.leftOrRight) {
                                if (shape.datas[i] > chart.candleMax) {
                                    chart.candleMax = shape.datas[i];
                                }
                                if (shape.datas[i] < chart.candleMin) {
                                    chart.candleMin = shape.datas[i];
                                }
                            }
                            else {
                                if (shape.datas[i] > chart.candleMaxRight) {
                                    chart.candleMaxRight = shape.datas[i];
                                }
                                if (shape.datas[i] < chart.candleMinRight) {
                                    chart.candleMinRight = shape.datas[i];
                                }
                            }
                        }
                    }
                    else if (shape.divIndex == 1) {
                        if (!load2 && i == chart.firstVisibleIndex) {
                            if (shape.leftOrRight) {
                                chart.volMax = shape.datas[i];
                                chart.volMin = shape.datas[i];
                            }
                            else {
                                chart.volMaxRight = shape.datas[i];
                                chart.volMinRight = shape.datas[i];
                            }
                            load2 = true;
                        }
                        else {
                            if (shape.leftOrRight) {
                                if (shape.datas[i] > chart.volMax) {
                                    chart.volMax = shape.datas[i];
                                }
                                if (shape.datas[i] < chart.volMin) {
                                    chart.volMin = shape.datas[i];
                                }
                            }
                            else {
                                if (shape.datas[i] > chart.volMaxRight) {
                                    chart.volMaxRight = shape.datas[i];
                                }
                                if (shape.datas[i] < chart.volMinRight) {
                                    chart.volMinRight = shape.datas[i];
                                }
                            }
                        }
                    }
                    else if (shape.divIndex == 2) {
                        if (!load3 && i == chart.firstVisibleIndex) {
                            if (shape.leftOrRight) {
                                chart.indMax = shape.datas[i];
                                chart.indMin = shape.datas[i];
                            }
                            else {
                                chart.indMaxRight = shape.datas[i];
                                chart.indMinRight = shape.datas[i];
                            }
                            load3 = true;
                        }
                        else {
                            if (shape.leftOrRight) {
                                if (shape.datas[i] > chart.indMax) {
                                    chart.indMax = shape.datas[i];
                                }
                                if (shape.datas[i] < chart.indMin) {
                                    chart.indMin = shape.datas[i];
                                }
                            }
                            else {
                                if (shape.datas[i] > chart.indMaxRight) {
                                    chart.indMaxRight = shape.datas[i];
                                }
                                if (shape.datas[i] < chart.indMinRight) {
                                    chart.indMinRight = shape.datas[i];
                                }
                            }
                        }
                    }
                    else if (shape.divIndex == 3) {
                        if (!load4 && i == chart.firstVisibleIndex) {
                            if (shape.leftOrRight) {
                                chart.indMax2 = shape.datas[i];
                                chart.indMin2 = shape.datas[i];
                            }
                            else {
                                chart.indMax2Right = shape.datas[i];
                                chart.indMin2Right = shape.datas[i];
                            }
                            load4 = true;
                        }
                        else {
                            if (shape.leftOrRight) {
                                if (shape.datas[i] > chart.indMax2) {
                                    chart.indMax2 = shape.datas[i];
                                }
                                if (shape.datas[i] < chart.indMin2) {
                                    chart.indMin2 = shape.datas[i];
                                }
                            }
                            else {
                                if (shape.datas[i] > chart.indMax2Right) {
                                    chart.indMax2Right = shape.datas[i];
                                }
                                if (shape.datas[i] < chart.indMin2Right) {
                                    chart.indMin2Right = shape.datas[i];
                                }
                            }
                        }
                    }
                }
            }
            if (shape.datas2.length > 0) {
                for (let i = chart.firstVisibleIndex; i <= lastValidIndex; i++) {
                    if (shape.divIndex == 0) {
                        if (shape.leftOrRight) {
                            if (shape.datas2[i] > chart.candleMax) {
                                chart.candleMax = shape.datas2[i];
                            }
                            if (shape.datas2[i] < chart.candleMin) {
                                chart.candleMin = shape.datas2[i];
                            }
                        }
                        else {
                            if (shape.datas2[i] > chart.candleMaxRight) {
                                chart.candleMaxRight = shape.datas2[i];
                            }
                            if (shape.datas2[i] < chart.candleMinRight) {
                                chart.candleMinRight = shape.datas2[i];
                            }
                        }
                    }
                    else if (shape.divIndex == 1) {
                        if (shape.leftOrRight) {
                            if (shape.datas2[i] > chart.volMax) {
                                chart.volMax = shape.datas2[i];
                            }
                            if (shape.datas2[i] < chart.volMin) {
                                chart.volMin = shape.datas2[i];
                            }
                        }
                        else {
                            if (shape.datas2[i] > chart.volMaxRight) {
                                chart.volMaxRight = shape.datas2[i];
                            }
                            if (shape.datas2[i] < chart.volMinRight) {
                                chart.volMinRight = shape.datas2[i];
                            }
                        }
                    }
                    else if (shape.divIndex == 2) {
                        if (shape.leftOrRight) {
                            if (shape.datas2[i] > chart.indMax) {
                                chart.indMax = shape.datas2[i];
                            }
                            if (shape.datas2[i] < chart.indMin) {
                                chart.indMin = shape.datas2[i];
                            }
                        }
                        else {
                            if (shape.datas2[i] > chart.indMaxRight) {
                                chart.indMaxRight = shape.datas2[i];
                            }
                            if (shape.datas2[i] < chart.indMinRight) {
                                chart.indMinRight = shape.datas2[i];
                            }
                        }
                    }
                    else if (shape.divIndex == 3) {
                        if (shape.leftOrRight) {
                            if (shape.datas2[i] > chart.indMax2) {
                                chart.indMax2 = shape.datas2[i];
                            }
                            if (shape.datas2[i] < chart.indMin2) {
                                chart.indMin2 = shape.datas2[i];
                            }
                        }
                        else {
                            if (shape.datas2[i] > chart.indMax2Right) {
                                chart.indMax2Right = shape.datas2[i];
                            }
                            if (shape.datas2[i] < chart.indMin2Right) {
                                chart.indMin2Right = shape.datas2[i];
                            }
                        }
                    }
                }
            }
        }
    }
    if (isTrend) {
        let subMax = Math.max(Math.abs(chart.candleMax - firstOpen), Math.abs(chart.candleMin - firstOpen));
        chart.candleMax = firstOpen + subMax;
        chart.candleMin = firstOpen - subMax;
    }
    else {
        if (chart.candleMax == 0 && chart.candleMin == 0) {
            chart.candleMax = 1;
            chart.candleMin = -1;
        }
        if (chart.volMax == 0 && chart.volMin == 0) {
            chart.volMax = 1;
            chart.volMin = -1;
        }
        if (chart.indMax == 0 && chart.indMin == 0) {
            chart.indMax = 1;
            chart.indMin = -1;
        }
        if (chart.indMax2 == 0 && chart.indMin2 == 0) {
            chart.indMax2 = 1;
            chart.indMin2 = -1;
        }
        if (chart.candleMaxRight == 0 && chart.candleMinRight == 0) {
            chart.candleMaxRight = 1;
            chart.candleMinRight = -1;
        }
        if (chart.volMaxRight == 0 && chart.volMinRight == 0) {
            chart.volMaxRight = 1;
            chart.volMinRight = -1;
        }
        if (chart.indMaxRight == 0 && chart.indMinRight == 0) {
            chart.indMaxRight = 1;
            chart.indMinRight = -1;
        }
        if (chart.indMax2Right == 0 && chart.indMin2Right == 0) {
            chart.indMax2Right = 1;
            chart.indMin2Right = -1;
        }
    }
}
/*
* 绘制线条
* chart:图表
* paint:绘图对象
* clipRect:裁剪区域
* divIndex:图层
* datas:数据
* color:颜色
* selected:是否选中
*/
function drawChartLines(chart, paint, clipRect, divIndex, datas, color, selected) {
    paint.beginPath();
    let lastX = 0, lastY = 0;
    let maxVisibleRecord = getChartMaxVisibleCount(chart, chart.hScalePixel, getChartWorkAreaWidth(chart));
    let lastValidIndex = chart.lastVisibleIndex;
    if (chart.lastValidIndex != -1) {
        lastValidIndex = chart.lastValidIndex;
    }
    for (let i = chart.firstVisibleIndex; i <= lastValidIndex; i++) {
        let x = getChartX(chart, i);
        let value = datas[i];
        let y = getChartY(chart, divIndex, value);
        if (i > chart.firstVisibleIndex) {
            paint.addLine(lastX, lastY, x, y);
        }
        lastX = x;
        lastY = y;
        if (selected) {
            let kPInterval = Math.floor(maxVisibleRecord / 30);
            if (kPInterval < 2) {
                kPInterval = 3;
            }
            if (i % kPInterval == 0) {
                paint.fillRect(color, x - 3, y - 3, x + 3, y + 3);
            }
        }
    }
    paint.drawPath(color, chart.lineWidthChart, null);
    paint.closePath();
}
/*
* 绘制线条到右轴
* chart:图表
* paint:绘图对象
* clipRect:裁剪区域
* divIndex:图层
* datas:数据
* color:颜色
* selected:是否选中
*/
function drawChartLinesInRight(chart, paint, clipRect, divIndex, datas, color, selected) {
    paint.beginPath();
    let lastX = 0, lastY = 0;
    let maxVisibleRecord = getChartMaxVisibleCount(chart, chart.hScalePixel, getChartWorkAreaWidth(chart));
    let lastValidIndex = chart.lastVisibleIndex;
    if (chart.lastValidIndex != -1) {
        lastValidIndex = chart.lastValidIndex;
    }
    for (let i = chart.firstVisibleIndex; i <= lastValidIndex; i++) {
        let x = getChartX(chart, i);
        let value = datas[i];
        let y = getChartYInRight(chart, divIndex, value);
        if (i > chart.firstVisibleIndex) {
            paint.addLine(lastX, lastY, x, y);
        }
        lastX = x;
        lastY = y;
        if (selected) {
            let kPInterval = Math.floor(maxVisibleRecord / 30);
            if (kPInterval < 2) {
                kPInterval = 3;
            }
            if (i % kPInterval == 0) {
                paint.fillRect(color, x - 3, y - 3, x + 3, y + 3);
            }
        }
    }
    paint.drawPath(color, chart.lineWidthChart, null);
    paint.closePath();
}
/*
* 绘制图表
* chart:图表
* paint:绘图对象
* clipRect:裁剪区域
*/
function drawChartStock(chart, paint, clipRect) {
    let lastValidIndex = chart.lastVisibleIndex;
    let cWidth = Math.floor(chart.hScalePixel - 3) / 2;
    if (cWidth < 0) {
        cWidth = 0;
    }
    if (chart.data && chart.data.length > 0) {
        let candleHeight = getCandleDivHeight(chart);
        let volHeight = getVolDivHeight(chart);
        let indHeight = getIndDivHeight(chart);
        let indHeight2 = getIndDivHeight2(chart);
        let isTrend = chart.cycle == "trend";
        if (chart.lastValidIndex != -1) {
            lastValidIndex = chart.lastValidIndex;
        }
        let maxVisibleRecord = getChartMaxVisibleCount(chart, chart.hScalePixel, getChartWorkAreaWidth(chart));
        paint.save();
        paint.setClip(chart.leftVScaleWidth, 0, chart.size.cx - chart.rightVScaleWidth, candleHeight);
        if (isTrend) {
            paint.beginPath();
            let lastX = 0, lastY = 0;
            for (let i = chart.firstVisibleIndex; i <= lastValidIndex; i++) {
                let x = getChartX(chart, i);
                let close = chart.data[i].close;
                let closeY = getChartY(chart, 0, close);
                if (i > chart.firstVisibleIndex) {
                    paint.addLine(lastX, lastY, x, closeY);
                }
                lastX = x;
                lastY = closeY;
            }
            paint.drawPath(chart.trendColor, chart.lineWidthChart, null);
            paint.closePath();
        }else{
            let hasMinTag = false, hasMaxTag = false;
            for (let i = chart.firstVisibleIndex; i <= lastValidIndex; i++) {
                let x = getChartX(chart, i);
                let open = chart.data[i].open;
                let close = chart.data[i].close;
                let high = chart.data[i].high;
                let low = chart.data[i].low;
                let openY = getChartY(chart, 0, open);
                let closeY = getChartY(chart, 0, close);
                let highY = getChartY(chart, 0, high);
                let lowY = getChartY(chart, 0, low);
                if (close >= open) {
                    if (close == open && chart.midColor != "none") {
                        paint.drawLine(chart.midColor, chart.lineWidthChart, null, x, highY, x, lowY);
                    }
                    else {
                        paint.drawLine(chart.upColor, chart.lineWidthChart, null, x, highY, x, lowY);
                    }
                    if (cWidth > 0) {
                        if (close == open) {
                            if (chart.midColor != "none") {
                                paint.drawLine(chart.midColor, chart.lineWidthChart, null, x - cWidth, closeY, x + cWidth, closeY);
                            }
                            else {
                                paint.drawLine(chart.upColor, chart.lineWidthChart, null, x - cWidth, closeY, x + cWidth, closeY);
                            }
                        }
                        else {
                            if (chart.candleStyle == "rect2") {
                                paint.fillRect(chart.backColor, x - cWidth, closeY, x + cWidth, openY);
                                paint.drawRect(chart.upColor, 1, null, x - cWidth, closeY, x + cWidth, openY);
                            }
                            else {
                                paint.fillRect(chart.upColor, x - cWidth, closeY, x + cWidth, openY);
                            }
                        }
                    }
                }
                else {
                    paint.drawLine(chart.downColor, chart.lineWidthChart, null, x, highY, x, lowY);
                    if (cWidth > 0) {
                        paint.fillRect(chart.downColor, x - cWidth, openY, x + cWidth, closeY);
                    }
                }
                if (chart.selectShape == "CANDLE") {
                    let kPInterval = Math.floor(maxVisibleRecord / 30);
                    if (kPInterval < 2) {
                        kPInterval = 3;
                    }
                    if (i % kPInterval == 0) {
                        paint.fillRect(chart.indicatorColors[0], x - 3, closeY - 3, x + 3, closeY + 3);
                    }
                }
                if (!hasMaxTag) {
                    if (high == chart.candleMax) {
                        let tag = high.toFixed(chart.candleDigit);
                        let tSize = paint.textSize(tag, chart.font);
                        paint.drawText(tag, chart.textColor, chart.font, x - tSize.cx / 2, highY - tSize.cy - 2);
                        hasMaxTag = true;
                    }
                }
                if (!hasMinTag) {
                    if (low == chart.candleMin) {
                        let tag = low.toFixed(chart.candleDigit);
                        let tSize = paint.textSize(tag, chart.font);
                        paint.drawText(tag, chart.textColor, chart.font, x - tSize.cx / 2, lowY + 2);
                        hasMinTag = true;
                    }
                }
            }
        }
        paint.restore();
        if(volHeight > 0){
            for (let i = chart.firstVisibleIndex; i <= lastValidIndex; i++) {
                let x = getChartX(chart, i);
                let open = chart.data[i].open;
                let close = chart.data[i].close;
                let openY = getChartY(chart, 0, open);
                let closeY = getChartY(chart, 0, close);
                let volume = chart.data[i].volume;
                let volY = getChartY(chart, 1, volume);
                let zeroY = getChartY(chart, 1, 0);
                if (close >= open) {
                    if (isTrend) {
                        paint.drawLine(chart.upColor, chart.lineWidthChart, null, x, volY, x, zeroY);
                    }
                    else {
                        if (cWidth > 0) {
                            if (chart.barStyle == "rect2") {
                                paint.fillRect(chart.backColor, x - cWidth, volY, x + cWidth, zeroY);
                                paint.drawRect(chart.upColor, 1, null, x - cWidth, volY, x + cWidth, zeroY);
                            }
                            else {
                                paint.fillRect(chart.upColor, x - cWidth, volY, x + cWidth, zeroY);
                            }
                        }
                        else {
                            paint.drawLine(chart.upColor, chart.lineWidthChart, null, x - cWidth, volY, x + cWidth, zeroY);
                        }
                    }
                }
                else {
                    if (isTrend) {
                        paint.drawLine(chart.downColor, chart.lineWidthChart, null, x, volY, x, zeroY);
                    }
                    else {
                        if (cWidth > 0) {
                            paint.fillRect(chart.downColor, x - cWidth, volY, x + cWidth, zeroY);
                        }
                        else {
                            paint.drawLine(chart.downColor, chart.lineWidthChart, null, x - cWidth, volY, x + cWidth, zeroY);
                        }
                    }
                }
                if (chart.selectShape == "VOL") {
                    let kPInterval = Math.floor(maxVisibleRecord / 30);
                    if (kPInterval < 2) {
                        kPInterval = 3;
                    }
                    if (i % kPInterval == 0) {
                        paint.fillRect(chart.indicatorColors[0], x - 3, volY - 3, x + 3, volY + 3);
                    }
                }
            }
        }
        if (!isTrend) {
            paint.save();
            paint.setClip(chart.leftVScaleWidth, 0, chart.size.cx - chart.rightVScaleWidth, candleHeight);
            if (chart.mainIndicator == "BOLL") {
                drawChartLines(chart, paint, clipRect, 0, chart.bollMid, chart.indicatorColors[0], (chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "MID") ? true : false);
                drawChartLines(chart, paint, clipRect, 0, chart.bollUp, chart.indicatorColors[1], (chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "UP") ? true : false);
                drawChartLines(chart, paint, clipRect, 0, chart.bollDown, chart.indicatorColors[2], (chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "DOWN") ? true : false);
            }
            else if (chart.mainIndicator == "MA") {
                drawChartLines(chart, paint, clipRect, 0, chart.ma5, chart.indicatorColors[0], (chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "5") ? true : false);
                drawChartLines(chart, paint, clipRect, 0, chart.ma10, chart.indicatorColors[1], (chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "10") ? true : false);
                drawChartLines(chart, paint, clipRect, 0, chart.ma20, chart.indicatorColors[2], (chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "20") ? true : false);
                drawChartLines(chart, paint, clipRect, 0, chart.ma30, chart.indicatorColors[5], (chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "30") ? true : false);
                drawChartLines(chart, paint, clipRect, 0, chart.ma120, chart.indicatorColors[4], (chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "120") ? true : false);
                drawChartLines(chart, paint, clipRect, 0, chart.ma250, chart.indicatorColors[3], (chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "250") ? true : false);
            }
            paint.restore();
        }
        if (indHeight > 0 || indHeight2 > 0) {
            for (let d = 2; d <= 3; d++) {
                let sind = chart.showIndicator;
                if (d == 3) {
                    sind = chart.showIndicator2;
                    if (indHeight2 <= 0) {
                        continue;
                    }
                }
                else {
                    if (indHeight <= 0) {
                        continue;
                    }
                }
                if (sind == "MACD") {
                    let zeroY = getChartY(chart, d, 0);
                    paint.drawLine(chart.indicatorColors[4], chart.lineWidthChart, null, chart.leftVScaleWidth, zeroY, getChartX(chart, chart.lastVisibleIndex), zeroY);
                    for (let i = chart.firstVisibleIndex; i <= lastValidIndex; i++) {
                        let x = getChartX(chart, i);
                        let macd = chart.allmacdarr[i];
                        let macdY = getChartY(chart, d, macd);
                        if (macdY < zeroY) {
                            paint.drawLine(chart.indicatorColors[3], chart.lineWidthChart, null, x, macdY, x, zeroY);
                        }
                        else {
                            paint.drawLine(chart.indicatorColors[4], chart.lineWidthChart, null, x, macdY, x, zeroY);
                        }
                        if (chart.selectShape == sind && chart.selectShapeEx == "MACD") {
                            let kPInterval = Math.floor(maxVisibleRecord / 30);
                            if (kPInterval < 2) {
                                kPInterval = 3;
                            }
                            if (i % kPInterval == 0) {
                                paint.fillRect(chart.indicatorColors[4], x - 3, macdY - 3, x + 3, macdY + 3);
                            }
                        }
                    }
                    drawChartLines(chart, paint, clipRect, d, chart.alldifarr, chart.indicatorColors[0], (chart.selectShape == sind && chart.selectShapeEx == "DIF") ? true : false);
                    drawChartLines(chart, paint, clipRect, d, chart.alldeaarr, chart.indicatorColors[1], (chart.selectShape == sind && chart.selectShapeEx == "DEA") ? true : false);
                }
                else if (sind == "KDJ") {
                    drawChartLines(chart, paint, clipRect, d, chart.kdjK, chart.indicatorColors[0], (chart.selectShape == sind && chart.selectShapeEx == "K") ? true : false);
                    drawChartLines(chart, paint, clipRect, d, chart.kdjD, chart.indicatorColors[1], (chart.selectShape == sind && chart.selectShapeEx == "D") ? true : false);
                    drawChartLines(chart, paint, clipRect, d, chart.kdjJ, chart.indicatorColors[2], (chart.selectShape == sind && chart.selectShapeEx == "J") ? true : false);
                }
                else if (sind == "RSI") {
                    drawChartLines(chart, paint, clipRect, d, chart.rsi1, chart.indicatorColors[5], (chart.selectShape == sind && chart.selectShapeEx == "6") ? true : false);
                    drawChartLines(chart, paint, clipRect, d, chart.rsi2, chart.indicatorColors[1], (chart.selectShape == sind && chart.selectShapeEx == "12") ? true : false);
                    drawChartLines(chart, paint, clipRect, d, chart.rsi3, chart.indicatorColors[2], (chart.selectShape == sind && chart.selectShapeEx == "24") ? true : false);
                }
                else if (sind == "BIAS") {
                    drawChartLines(chart, paint, clipRect, d, chart.bias1, chart.indicatorColors[5], (chart.selectShape == sind && chart.selectShapeEx == "1") ? true : false);
                    drawChartLines(chart, paint, clipRect, d, chart.bias2, chart.indicatorColors[1], (chart.selectShape == sind && chart.selectShapeEx == "2") ? true : false);
                    drawChartLines(chart, paint, clipRect, d, chart.bias3, chart.indicatorColors[2], (chart.selectShape == sind && chart.selectShapeEx == "3") ? true : false);
                }
                else if (sind == "ROC") {
                    drawChartLines(chart, paint, clipRect, d, chart.roc, chart.indicatorColors[0], (chart.selectShape == sind && chart.selectShapeEx == "ROC") ? true : false);
                    drawChartLines(chart, paint, clipRect, d, chart.rocMa, chart.indicatorColors[1], (chart.selectShape == sind && chart.selectShapeEx == "ROCMA") ? true : false);
                }
                else if (sind == "WR") {
                    drawChartLines(chart, paint, clipRect, d, chart.wr1, chart.indicatorColors[0], (chart.selectShape == sind && chart.selectShapeEx == "1") ? true : false);
                    drawChartLines(chart, paint, clipRect, d, chart.wr2, chart.indicatorColors[1], (chart.selectShape == sind && chart.selectShapeEx == "2") ? true : false);
                }
                else if (sind == "CCI") {
                    drawChartLines(chart, paint, clipRect, d, chart.cci, chart.indicatorColors[0], (chart.selectShape == sind) ? true : false);
                }
                else if (sind == "BBI") {
                    drawChartLines(chart, paint, clipRect, d, chart.bbi, chart.indicatorColors[0], (chart.selectShape == sind) ? true : false);
                }
                else if (sind == "TRIX") {
                    drawChartLines(chart, paint, clipRect, d, chart.trix, chart.indicatorColors[0], (chart.selectShape == sind && chart.selectShapeEx == "TRIX") ? true : false);
                    drawChartLines(chart, paint, clipRect, d, chart.trixMa, chart.indicatorColors[1], (chart.selectShape == sind && chart.selectShapeEx == "TRIXMA") ? true : false);
                }
                else if (sind == "DMA") {
                    drawChartLines(chart, paint, clipRect, d, chart.dma1, chart.indicatorColors[0], (chart.selectShape == sind && chart.selectShapeEx == "DIF") ? true : false);
                    drawChartLines(chart, paint, clipRect, d, chart.dma2, chart.indicatorColors[1], (chart.selectShape == sind && chart.selectShapeEx == "DIFMA") ? true : false);
                }
            }
        }
    }
    //绘制扩展线条
    if (chart.shapes.length > 0) {
        for (let i = 0; i < chart.shapes.length; i++) {
            let shape = chart.shapes[i];
            if (shape.shapeType == "bar") {
                for (let j = chart.firstVisibleIndex; j <= lastValidIndex; j++) {
                    if (shape.showHideDatas.length > j && shape.showHideDatas[j].toString() == "0") {
                        continue;
                    }
                    let x = getChartX(chart, j);
                    let y1 = 0;
                    if (shape.leftOrRight) {
                        y1 = getChartY(chart, shape.divIndex, shape.datas[j]);
                    }
                    else {
                        y1 = getChartYInRight(chart, shape.divIndex, shape.datas[j]);
                    }
                    if (shape.style != "2color") {
                        let y2 = 0;
                        if (shape.leftOrRight) {
                            y2 = getChartY(chart, shape.divIndex, shape.datas2[j]);
                        }
                        else {
                            y2 = getChartYInRight(chart, shape.divIndex, shape.datas2[j]);
                        }
                        if (y1 >= y2) {
                            paint.fillRect(shape.color, x - cWidth, y2, x + cWidth, y1);
                        }
                        else {
                            paint.fillRect(shape.color, x - cWidth, y1, x + cWidth, y2);
                        }
                    }
                    else {
                        let y2 = 0;
                        if (shape.leftOrRight) {
                            y2 = getChartY(chart, shape.divIndex, 0);
                        }
                        else {
                            y2 = getChartYInRight(chart, shape.divIndex, 0);
                        }
                        if (y1 >= y2) {
                            paint.drawLine(shape.color2, 1, null, x, y1, x, y2);
                        }
                        else {
                            paint.drawLine(shape.color, 1, null, x, y1, x, y2);
                        }
                        if (j == lastValidIndex) {
                            paint.drawLine(shape.color2, 1, null, chart.leftVScaleWidth, y2, chart.size.cx - chart.rightVScaleWidth, y2);
                        }
                    }
                }
            }
            else if (shape.shapeType == "text") {
                for (let j = chart.firstVisibleIndex; j <= lastValidIndex; j++) {
                    let x = getChartX(chart, j);
                    if (shape.datas[j] != 0) {
                        let y1 = 0;
                        if (shape.leftOrRight) {
                            y1 = getChartY(chart, shape.divIndex, shape.value);
                        }
                        else {
                            y1 = getChartYInRight(chart, shape.divIndex, shape.value);
                        }
                        let drawText = shape.text;
                        let tSize = paint.textSize(drawText, "Default,12");
                        paint.drawText(drawText, shape.color, "Default,12", x - tSize.cx / 2, y1);
                    }
                }
            }
            else {
                if (shape.leftOrRight) {
                    drawChartLines(chart, paint, clipRect, shape.divIndex, shape.datas, shape.color, (chart.selectShape == shape.shapeName) ? true : false);
                }
                else {
                    drawChartLinesInRight(chart, paint, clipRect, shape.divIndex, shape.datas, shape.color, (chart.selectShape == shape.shapeName) ? true : false);
                }
            }
        }
    }
}
/*
* 获取数据
* chart:图表
*/
function calcChartIndicator(chart) {
    clearDataArr(chart);
    if (chart.data.length > 0) {
        let closeArr = [];
        let highArr = [];
        let lowArr = [];
        if (chart.data.length > 0) {
            for (let i = 0; i < chart.data.length; i++) {
                closeArr.push(chart.data[i].close);
                highArr.push(chart.data[i].high);
                lowArr.push(chart.data[i].low);
            }
        }
        chart.closeArr = closeArr;
        if (chart.mainIndicator == "BOLL") {
            getBollData(closeArr, 20, chart.bollUp, chart.bollMid, chart.bollDown);
        }
        else if (chart.mainIndicator == "MA") {
            chart.ma5 = maValue(closeArr, 5);
            chart.ma10 = maValue(closeArr, 10);
            chart.ma20 = maValue(closeArr, 20);
            chart.ma30 = maValue(closeArr, 30);
            chart.ma120 = maValue(closeArr, 120);
            chart.ma250 = maValue(closeArr, 250);
        }
        if (chart.showIndicator == "BIAS" || chart.showIndicator2 == "BIAS") {
            getBIASData(closeArr, 6, 12, 24, chart.bias1, chart.bias2, chart.bias3);
        }
        if (chart.showIndicator == "DMA" || chart.showIndicator2 == "DMA") {
            getDMAData(closeArr, 10, 50, chart.dma1, chart.dma2);
        }
        if (chart.showIndicator == "BBI" || chart.showIndicator2 == "BBI") {
            getBBIData(closeArr, 3, 6, 12, 24, chart.bbi);
        }
        if (chart.showIndicator == "RSI" || chart.showIndicator2 == "RSI") {
            getRSIData(closeArr, 6, 12, 24, chart.rsi1, chart.rsi2, chart.rsi3);
        }
        if (chart.showIndicator == "ROC" || chart.showIndicator2 == "ROC") {
            getRocData(closeArr, 12, 6, chart.roc, chart.rocMa);
        }
        if (chart.showIndicator == "TRIX" || chart.showIndicator2 == "TRIX") {
            getTRIXData(closeArr, 9, chart.trix, chart.trixMa);
        }
        if (chart.showIndicator == "KDJ" || chart.showIndicator2 == "KDJ") {
            getKDJData(highArr, lowArr, closeArr, 9, 3, 3, chart.kdjK, chart.kdjD, chart.kdjJ);
        }
        if (chart.showIndicator == "WR" || chart.showIndicator2 == "WR") {
            getWRData(highArr, lowArr, closeArr, 5, 10, chart.wr1, chart.wr2);
        }
        if (chart.showIndicator == "CCI" || chart.showIndicator2 == "CCI") {
            getCCIData(highArr, lowArr, closeArr, 14, chart.cci);
        }
        if (chart.showIndicator == "MACD" || chart.showIndicator2 == "MACD") {
            //缓存MACD数据
            chart.allema12.push(closeArr[0]);
            chart.allema26.push(closeArr[0]);
            chart.alldeaarr.push(0);
            for (let i = 1; i < closeArr.length; i++) {
                chart.allema12.push(getEMA(12, closeArr[i], chart.allema12[i - 1]));
                chart.allema26.push(getEMA(26, closeArr[i], chart.allema26[i - 1]));
            }
            chart.alldifarr = getDIF(chart.allema12, chart.allema26);
            for (let i = 1; i < chart.alldifarr.length; i++) {
                chart.alldeaarr.push(chart.alldeaarr[i - 1] * 8 / 10 + chart.alldifarr[i] * 2 / 10);
            }
            chart.allmacdarr = getMACD(chart.alldifarr, chart.alldeaarr);
        }
        calculateChartMaxMin(chart);
    }
    calculateChartMaxMin(chart);
}
/*
* 计算EMA
* n:周期
* value:当前数据
* lastEMA:上期数据
*/
function getEMA(n, value, lastEMA) {
    return (value * 2 + lastEMA * (n - 1)) / (n + 1);
}
/*
* 计算MACD
* dif:DIF数据
* dea:DEA数据
*/
function getMACD(dif, dea) {
    let result = [];
    for (let i = 0; i < dif.length; i++) {
        result.push((dif[i] - dea[i]) * 2);
    }
    return result;
}
/*
* 计算DIF
* close12:12日数据
* close26:26日数据
*/
function getDIF(close12, close26) {
    let result = [];
    for (let i = 0; i < close12.length; i++) {
        result.push(close12[i] - close26[i]);
    }
    return result;
}
/*
* 清除缓存数据方法
* chart:图表
*/
function clearDataArr(chart) {
    chart.allema12 = [];
    chart.allema26 = [];
    chart.alldifarr = [];
    chart.alldeaarr = [];
    chart.allmacdarr = [];
    chart.bollUp = [];
    chart.bollDown = [];
    chart.bollMid = [];
    chart.bias1 = [];
    chart.bias2 = [];
    chart.bias3 = [];
    chart.kdjK = [];
    chart.kdjD = [];
    chart.kdjJ = [];
    chart.rsi1 = [];
    chart.rsi2 = [];
    chart.rsi3 = [];
    chart.roc = [];
    chart.rocMa = [];
    chart.wr1 = [];
    chart.wr2 = [];
    chart.cci = [];
    chart.bbi = [];
    chart.trix = [];
    chart.trixMa = [];
    chart.dma1 = [];
    chart.dma2 = [];
    chart.ma5 = [];
    chart.ma10 = [];
    chart.ma20 = [];
    chart.ma30 = [];
    chart.ma120 = [];
    chart.ma250 = [];
}
/*
* 判断是否选中线条
* chart:图表
* mp:坐标
* divIndex:层索引
* datas:数据
* curIndex:当前索引
*/
function selectLines(chart, mp, divIndex, datas, curIndex) {
    if (datas.length > 0) {
        let topY = getChartY(chart, divIndex, datas[curIndex]);
        if (chart.hScalePixel <= 1) {
            if (mp.y >= topY - 8 && mp.y <= topY + 8) {
                return true;
            }
        }
        else {
            let index = curIndex;
            let scaleX = getChartX(chart, index);
            let judgeTop = 0;
            let judgeScaleX = scaleX;
            if (mp.x >= scaleX) {
                let leftIndex = curIndex + 1;
                if (curIndex < chart.lastVisibleIndex) {
                    let rightValue = datas[leftIndex];
                    judgeTop = getChartY(chart, divIndex, rightValue);
                }
                else {
                    judgeTop = topY;
                }
            }
            else {
                judgeScaleX = scaleX - chart.hScalePixel;
                let rightIndex = curIndex - 1;
                if (curIndex > 0) {
                    let leftValue = datas[rightIndex];
                    judgeTop = getChartY(chart, divIndex, leftValue);
                }
                else {
                    judgeTop = topY;
                }
            }
            let lineWidth = 4;
            let judgeX = 0, judgeY = 0, judgeW = 0, judgeH = 0;
            if (judgeTop >= topY) {
                judgeX = judgeScaleX;
                judgeY = topY - 2 - lineWidth;
                judgeW = chart.hScalePixel;
                judgeH = judgeTop - topY + lineWidth < 4 ? 4 : judgeTop - topY + 4 + lineWidth;
            }
            else {
                judgeX = judgeScaleX;
                judgeY = judgeTop - 2 - lineWidth / 2;
                judgeW = chart.hScalePixel;
                judgeH = topY - judgeTop + lineWidth < 4 ? 4 : topY - judgeTop + 4 + lineWidth;
            }
            if (mp.x >= judgeX && mp.x <= judgeX + judgeW && mp.y >= judgeY && mp.y <= judgeY + judgeH) {
                return true;
            }
        }
    }
    return false;
}
/*
* 判断是否在右轴选中线条
* chart:图表
* mp:坐标
* divIndex:层索引
* datas:数据
* curIndex:当前索引
*/
function selectLinesInRight(chart, mp, divIndex, datas, curIndex) {
    if (datas.length > 0) {
        let topY = getChartYInRight(chart, divIndex, datas[curIndex]);
        if (chart.hScalePixel <= 1) {
            if (mp.y >= topY - 8 && mp.y <= topY + 8) {
                return true;
            }
        }
        else {
            let index = curIndex;
            let scaleX = getChartX(chart, index);
            let judgeTop = 0;
            let judgeScaleX = scaleX;
            if (mp.x >= scaleX) {
                let leftIndex = curIndex + 1;
                if (curIndex < chart.lastVisibleIndex) {
                    let rightValue = datas[leftIndex];
                    judgeTop = getChartYInRight(chart, divIndex, rightValue);
                }
                else {
                    judgeTop = topY;
                }
            }
            else {
                judgeScaleX = scaleX - chart.hScalePixel;
                let rightIndex = curIndex - 1;
                if (curIndex > 0) {
                    let leftValue = datas[rightIndex];
                    judgeTop = getChartYInRight(chart, divIndex, leftValue);
                }
                else {
                    judgeTop = topY;
                }
            }
            let lineWidth = 4;
            let judgeX = 0, judgeY = 0, judgeW = 0, judgeH = 0;
            if (judgeTop >= topY) {
                judgeX = judgeScaleX;
                judgeY = topY - 2 - lineWidth;
                judgeW = chart.hScalePixel;
                judgeH = judgeTop - topY + lineWidth < 4 ? 4 : judgeTop - topY + 4 + lineWidth;
            }
            else {
                judgeX = judgeScaleX;
                judgeY = judgeTop - 2 - lineWidth / 2;
                judgeW = chart.hScalePixel;
                judgeH = topY - judgeTop + lineWidth < 4 ? 4 : topY - judgeTop + 4 + lineWidth;
            }
            if (mp.x >= judgeX && mp.x <= judgeX + judgeW && mp.y >= judgeY && mp.y <= judgeY + judgeH) {
                return true;
            }
        }
    }
    return false;
}
/*
* 判断是否选中图形
* chart:图表
* mp:坐标
*/
function selectShape(chart, mp) {
    chart.selectShape = "";
    chart.selectShapeEx = "";
    let candleHeight = getCandleDivHeight(chart);
    let volHeight = getVolDivHeight(chart);
    let indHeight = getIndDivHeight(chart);
    let indHeight2 = getIndDivHeight2(chart);
    let index = getChartIndex(chart, mp);
    if (mp.y >= candleHeight + volHeight + indHeight && mp.y <= candleHeight + volHeight + indHeight + indHeight2) {
        if (chart.showIndicator2 == "MACD") {
            if (selectLines(chart, mp, 3, chart.allmacdarr, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "MACD";
            }
            if (selectLines(chart, mp, 3, chart.alldifarr, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "DIF";
            }
            else if (selectLines(chart, mp, 3, chart.alldeaarr, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "DEA";
            }
        }
        else if (chart.showIndicator2 == "KDJ") {
            if (selectLines(chart, mp, 3, chart.kdjK, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "K";
            }
            else if (selectLines(chart, mp, 3, chart.kdjD, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "D";
            }
            else if (selectLines(chart, mp, 3, chart.kdjJ, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "J";
            }
        }
        else if (chart.showIndicator2 == "RSI") {
            if (selectLines(chart, mp, 3, chart.rsi1, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "6";
            }
            else if (selectLines(chart, mp, 3, chart.rsi2, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "12";
            }
            else if (selectLines(chart, mp, 3, chart.rsi3, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "24";
            }
        }
        else if (chart.showIndicator2 == "BIAS") {
            if (selectLines(chart, mp, 3, chart.bias1, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "1";
            }
            else if (selectLines(chart, mp, 3, chart.bias2, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "2";
            }
            else if (selectLines(chart, mp, 3, chart.bias3, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "3";
            }
        }
        else if (chart.showIndicator2 == "ROC") {
            if (selectLines(chart, mp, 3, chart.roc, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "ROC";
            }
            else if (selectLines(chart, mp, 3, chart.rocMa, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "ROCMA";
            }
        }
        else if (chart.showIndicator2 == "WR") {
            if (selectLines(chart, mp, 3, chart.wr1, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "1";
            }
            else if (selectLines(chart, mp, 3, chart.wr2, index)) {
                chart.selectShape = "WR";
                chart.selectShapeEx = "2";
            }
        }
        else if (chart.showIndicator2 == "CCI") {
            if (selectLines(chart, mp, 3, chart.cci, index)) {
                chart.selectShape = chart.showIndicator2;
            }
        }
        else if (chart.showIndicator2 == "BBI") {
            if (selectLines(chart, mp, 3, chart.bbi, index)) {
                chart.selectShape = chart.showIndicator2;
            }
        }
        else if (chart.showIndicator2 == "TRIX") {
            if (selectLines(chart, mp, 3, chart.trix, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "TRIX";
            }
            else if (selectLines(chart, mp, 3, chart.trixMa, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "TRIXMA";
            }
        }
        else if (chart.showIndicator2 == "DMA") {
            if (selectLines(chart, mp, 3, chart.dma1, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "DIF";
            }
            else if (selectLines(chart, mp, 3, chart.dma2, index)) {
                chart.selectShape = chart.showIndicator2;
                chart.selectShapeEx = "DIFMA";
            }
        }
    }
    else if (mp.y >= candleHeight + volHeight && mp.y <= candleHeight + volHeight + indHeight) {
        if (chart.showIndicator == "MACD") {
            let macdY = getChartY(chart, 2, chart.allmacdarr[index]);
            let zeroY = getChartY(chart, 2, 0);
            if (selectLines(chart, mp, 2, chart.allmacdarr, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "MACD";
            }
            if (selectLines(chart, mp, 2, chart.alldifarr, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "DIF";
            }
            else if (selectLines(chart, mp, 2, chart.alldeaarr, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "DEA";
            }
        }
        else if (chart.showIndicator == "KDJ") {
            if (selectLines(chart, mp, 2, chart.kdjK, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "K";
            }
            else if (selectLines(chart, mp, 2, chart.kdjD, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "D";
            }
            else if (selectLines(chart, mp, 2, chart.kdjJ, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "J";
            }
        }
        else if (chart.showIndicator == "RSI") {
            if (selectLines(chart, mp, 2, chart.rsi1, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "6";
            }
            else if (selectLines(chart, mp, 2, chart.rsi2, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "12";
            }
            else if (selectLines(chart, mp, 2, chart.rsi3, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "24";
            }
        }
        else if (chart.showIndicator == "BIAS") {
            if (selectLines(chart, mp, 2, chart.bias1, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "1";
            }
            else if (selectLines(chart, mp, 2, chart.bias2, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "2";
            }
            else if (selectLines(chart, mp, 2, chart.bias3, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "3";
            }
        }
        else if (chart.showIndicator == "ROC") {
            if (selectLines(chart, mp, 2, chart.roc, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "ROC";
            }
            else if (selectLines(chart, mp, 2, chart.rocMa, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "ROCMA";
            }
        }
        else if (chart.showIndicator == "WR") {
            if (selectLines(chart, mp, 2, chart.wr1, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "1";
            }
            else if (selectLines(chart, mp, 2, chart.wr2, index)) {
                chart.selectShape = "WR";
                chart.selectShapeEx = "2";
            }
        }
        else if (chart.showIndicator == "CCI") {
            if (selectLines(chart, mp, 2, chart.cci, index)) {
                chart.selectShape = chart.showIndicator;
            }
        }
        else if (chart.showIndicator == "BBI") {
            if (selectLines(chart, mp, 2, chart.bbi, index)) {
                chart.selectShape = chart.showIndicator;
            }
        }
        else if (chart.showIndicator == "TRIX") {
            if (selectLines(chart, mp, 2, chart.trix, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "TRIX";
            }
            else if (selectLines(chart, mp, 2, chart.trixMa, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "TRIXMA";
            }
        }
        else if (chart.showIndicator == "DMA") {
            if (selectLines(chart, mp, 2, chart.dma1, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "DIF";
            }
            else if (selectLines(chart, mp, 2, chart.dma2, index)) {
                chart.selectShape = chart.showIndicator;
                chart.selectShapeEx = "DIFMA";
            }
        }
    }
    else if (mp.y >= candleHeight && mp.y <= candleHeight + volHeight) {
        let volY = getChartY(chart, 1, chart.data[index].volume);
        let zeroY = getChartY(chart, 1, 0);
        if (mp.y >= Math.min(volY, zeroY) && mp.y <= Math.max(volY, zeroY)) {
            chart.selectShape = "VOL";
        }
    }
    else if (mp.y >= 0 && mp.y <= candleHeight) {
        let isTrend = chart.cycle == "trend";
        if (!isTrend) {
            if (chart.mainIndicator == "BOLL") {
                if (selectLines(chart, mp, 0, chart.bollMid, index)) {
                    chart.selectShape = chart.mainIndicator;
                    chart.selectShapeEx = "MID";
                }
                else if (selectLines(chart, mp, 0, chart.bollUp, index)) {
                    chart.selectShape = chart.mainIndicator;
                    chart.selectShapeEx = "UP";
                }
                else if (selectLines(chart, mp, 0, chart.bollDown, index)) {
                    chart.selectShape = chart.mainIndicator;
                    chart.selectShapeEx = "DOWN";
                }
            }
            else if (chart.mainIndicator == "MA") {
                if (selectLines(chart, mp, 0, chart.ma5, index)) {
                    chart.selectShape = chart.mainIndicator;
                    chart.selectShapeEx = "5";
                }
                else if (selectLines(chart, mp, 0, chart.ma10, index)) {
                    chart.selectShape = chart.mainIndicator;
                    chart.selectShapeEx = "10";
                }
                else if (selectLines(chart, mp, 0, chart.ma20, index)) {
                    chart.selectShape = chart.mainIndicator;
                    chart.selectShapeEx = "20";
                }
                else if (selectLines(chart, mp, 0, chart.ma30, index)) {
                    chart.selectShape = chart.mainIndicator;
                    chart.selectShapeEx = "30";
                }
                else if (selectLines(chart, mp, 0, chart.ma120, index)) {
                    chart.selectShape = chart.mainIndicator;
                    chart.selectShapeEx = "120";
                }
                else if (selectLines(chart, mp, 0, chart.ma250, index)) {
                    chart.selectShape = chart.mainIndicator;
                    chart.selectShapeEx = "250";
                }
            }
        }
        if (chart.selectShape == "") {
            let highY = getChartY(chart, 0, chart.data[index].high);
            let lowY = getChartY(chart, 0, chart.data[index].low);
            if (isTrend) {
                if (selectLines(chart, mp, 0, chart.closeArr, index)) {
                    chart.selectShape = "CANDLE";
                }
            }
            else {
                if (mp.y >= Math.min(lowY, highY) && mp.y <= Math.max(lowY, highY)) {
                    chart.selectShape = "CANDLE";
                }
            }
        }
    }
    if (chart.shapes.length > 0) {
        for (let i = 0; i < chart.shapes.length; i++) {
            let shape = chart.shapes[i];
            if (shape.leftOrRight) {
                if (selectLines(chart, mp, shape.divIndex, shape.datas, index)) {
                    chart.selectShape = shape.shapeName;
                    break;
                }
            }
            else {
                if (selectLinesInRight(chart, mp, shape.divIndex, shape.datas, index)) {
                    chart.selectShape = shape.shapeName;
                    break;
                }
            }
        }
    }
}
/*
* 触摸开始方法
* view:视图
* firstTouch:是否第一次触摸
* firstPoint:第一次触摸的坐标
* secondTouch:是否第二次触摸
* secondPoint:第二次触摸的坐标
*/
function onTouchBeginDefault(view, firstTouch, firstPoint, secondTouch, secondPoint) {
    if (view.onTouchBegin) {
        view.onTouchBegin(view, firstTouch, firstPoint, secondTouch, secondPoint);
        return;
    }
    if (view.viewType == "tree") {
        touchDownTree(view, firstTouch, firstPoint, secondTouch, secondPoint, 1);
    }
    else if (view.viewType == "grid") {
        touchDownGrid(view, firstTouch, firstPoint, secondTouch, secondPoint, 1);
    }
    else if (view.viewType == "div" || view.viewType == "layout" || view.viewType == "menu") {
        touchDownDiv(view, firstTouch, firstPoint, secondTouch, secondPoint, 1);
    }
    else if (view.viewType == "calendar") {
        clickCalendar(view, firstPoint);
    }
    else if (view.viewType == "button") {
        invalidateView(view);
    }
    else if (view.viewType == "chart") {
        touchDownChart(view, firstTouch, firstPoint, secondTouch, secondPoint);
    }
}
/*
* 触摸移动方法
* view:视图
* firstTouch:是否第一次触摸
* firstPoint:第一次触摸的坐标
* secondTouch:是否第二次触摸
* secondPoint:第二次触摸的坐标
*/
function onTouchMoveDefault(view, firstTouch, firstPoint, secondTouch, secondPoint) {
    if (view.onTouchMove) {
        view.onTouchMove(view, firstTouch, firstPoint, secondTouch, secondPoint);
        return;
    }
    if (view.viewType == "tree") {
        touchMoveTree(view, firstTouch, firstPoint, secondTouch, secondPoint);
        invalidateView(view);
    }
    else if (view.viewType == "grid") {
        touchMoveGrid(view, firstTouch, firstPoint, secondTouch, secondPoint);
        invalidateView(view);
    }
    else if (view.viewType == "div" || view.viewType == "layout" || view.viewType == "menu") {
        touchMoveDiv(view, firstTouch, firstPoint, secondTouch, secondPoint);
        invalidateView(view);
    }
    else if (view.viewType == "chart") {
        touchMoveChart(view, firstTouch, firstPoint, secondTouch, secondPoint);
        invalidateView(view);
    }
    else if (view.viewType == "menuitem") {
        touchMoveMenuItem(view);
    }
    else {
        invalidateView(view);
    }
}
/*
* 触摸结束方法
* view:视图
* firstTouch:是否第一次触摸
* firstPoint:第一次触摸的坐标
* secondTouch:是否第二次触摸
* secondPoint:第二次触摸的坐标
*/
function onTouchEndDefault(view, firstTouch, firstPoint, secondTouch, secondPoint) {
    if (view.onTouchEnd) {
        view.onTouchEnd(view, firstTouch, firstPoint, secondTouch, secondPoint);
        return;
    }
    if (view.viewType == "tree") {
        touchUpTree(view, firstTouch, firstPoint, secondTouch, secondPoint, 1);
    }
    else if (view.viewType == "grid") {
        touchUpGrid(view, firstTouch, firstPoint, secondTouch, secondPoint, 1);
    }
    else if (view.viewType == "div" || view.viewType == "layout" || view.viewType == "menu") {
        touchUpDiv(view, firstTouch, firstPoint, secondTouch, secondPoint, 1);
    }
    else if (view.viewType == "chart") {
        let chart = view;
        chart.firstTouchIndexCacheChart = -1;
        chart.secondTouchIndexCacheChart = -1;
    }
    invalidateView(view);
}
/*
* 鼠标点击实现方法
* view:视图
* firstTouch:是否第一次触摸
* firstPoint:第一次触摸的坐标
* secondTouch:是否第二次触摸
* secondPoint:第二次触摸的坐标
*/
function onClickDefault(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks) {
    if (view.onClick) {
        view.onClick(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
        return;
    }
    if (view.viewType == "tabbutton") {
        let tabView = view.parent;
        if (tabView.tabPages.length > 0) {
            for (let i = 0; i < tabView.tabPages.length; i++) {
                if (tabView.tabPages[i].headerButton == view) {
                    selectTabPage(tabView, tabView.tabPages[i]);
                    break;
                }
            }
        }
        invalidateView(tabView);
    }
    else if (view.viewType == "radiobutton") {
        clickRadioButton(view, firstPoint);
        invalidate(view.paint);
    }
    else if (view.viewType == "checkbox") {
        clickCheckBox(view, firstPoint);
        invalidateView(view.parent);
    }
    else if (view.viewType == "menuitem") {
        clickMenuItem(view);
    }
    else if (view.viewType == "combobox") {
        clickComboBox(view);
    }
}
/*
* 重绘背景的实现方法
* view:视图
* paint:绘图对象
* clipRect:裁剪区域
*/
function onPaintDefault(view, paint, clipRect) {
    if (view.onPaint) {
        view.onPaint(view, paint, clipRect);
        return;
    }
    if (view.viewType == "chart") {
        drawChart(view, paint, clipRect);
    }
    else if (view.viewType == "div" || view.viewType == "layout" || view.viewType == "tabpage") {
        drawDiv(view, paint, clipRect);
    }
    else if (view.viewType == "grid") {
        drawDiv(view, paint, clipRect);
        drawGrid(view, paint, clipRect);
    }
    else if (view.viewType == "tree") {
        drawDiv(view, paint, clipRect);
        drawTree(view, paint, clipRect);
    }
    else if (view.viewType == "calendar") {
        drawCalendar(view, paint);
    }
    else if (view.viewType == "label") {
        if (view.textColor && view.textColor != "none") {
            let tSize = paint.textSize(view.text, view.font);
            paint.drawText(view.text, view.textColor, view.font, 0, view.size.cy / 2 + 1 - tSize.cy / 2);
        }
    }
    else if (view.viewType == "textbox" && !view.input) {
        drawDiv(view, paint, clipRect);
        if (view.textColor && view.textColor != "none") {
            let tSize = paint.textSize(view.text, view.font);
            paint.drawText(view.text, view.textColor, view.font, 2, view.size.cy / 2 + 1 - tSize.cy / 2);
        }
    }
    else if (view.viewType == "radiobutton") {
        drawRadioButton(view, paint, clipRect);
    }
    else if (view.viewType == "checkbox") {
        drawCheckBox(view, paint, clipRect);
    }
    else if (view.viewType == "menuitem") {
        drawMenuItem(view, paint, clipRect);
    }
    else if (view.viewType == "combobox") {
        drawComboBox(view, paint, clipRect);
    }
    else {
        drawButton(view, paint, clipRect);
    }
}
/*
* 重绘边框的实现方法
* view:视图
* paint:绘图对象
* clipRect:裁剪区域
*/
function onPaintBorderDefault(view, paint, clipRect) {
    if (view.onPaintBorder) {
        view.onPaintBorder(view, paint, clipRect);
        return;
    }
    if (view.viewType == "grid") {
        drawGridScrollBar(view, paint, clipRect);
        drawDivBorder(view, paint, clipRect);
    }
    else if (view.viewType == "tree") {
        drawTreeScrollBar(view, paint, clipRect);
        drawDivBorder(view, paint, clipRect);
    }
    else if (view.viewType == "div" || view.viewType == "layout" || view.viewType == "menu") {
        drawDivScrollBar(view, paint, clipRect);
        drawDivBorder(view, paint, clipRect);
    }
    else if (view.viewType == "tabpage") {
        drawDivBorder(view, paint, clipRect);
    }
    else if (view.viewType == "tabview") {
        drawTabViewBorder(view, paint, clipRect);
    }
    else if (view.viewType == "textbox" && !view.input) {
        drawDivBorder(view, paint, clipRect);
    }
}
/*
* 鼠标按下实现方法
* view:视图
* mp:坐标
* button:按钮
* clicks:点击次数
* delta:滚轮值
*/
function onMouseDownDefault(view, mp, buttons, clicks, delta) {
    if (view.onMouseDown) {
        view.onMouseDown(view, mp, buttons, clicks, delta);
        return;
    }
    let firstTouch = false, secondTouch = false;
    let firstPoint = mp, secondPoint = mp;
    if (buttons == 1) {
        firstTouch = true;
    }
    else if (buttons == 2) {
        secondTouch = true;
    }
    if (view.viewType == "tree") {
        touchDownTree(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
    }
    else if (view.viewType == "grid") {
        touchDownGrid(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
    }
    else if (view.viewType == "div" || view.viewType == "layout" || view.viewType == "menu") {
        touchDownDiv(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
    }
    else if (view.viewType == "calendar") {
        clickCalendar(view, mp);
    }
    else if (view.viewType == "button") {
        invalidateView(view);
    }
    else if (view.viewType == "chart") {
        touchDownChart(view, firstTouch, firstPoint, secondTouch, secondPoint);
    }
}
/*
* 鼠标移动实现方法
* view:视图
* mp:坐标
* button:按钮
* clicks:点击次数
* delta:滚轮值
*/
function onMouseMoveDefault(view, mp, buttons, clicks, delta) {
    if (view.onMouseMove) {
        view.onMouseMove(view, mp, buttons, clicks, delta);
        return;
    }
    let firstTouch = false, secondTouch = false;
    let firstPoint = mp, secondPoint = mp;
    if (buttons == 1) {
        firstTouch = true;
    }
    else if (buttons == 2) {
        secondTouch = true;
    }
    if (view.viewType == "tree") {
        touchMoveTree(view, firstTouch, firstPoint, secondTouch, secondPoint);
        invalidateView(view);
    }
    else if (view.viewType == "grid") {
        touchMoveGrid(view, firstTouch, firstPoint, secondTouch, secondPoint);
        invalidateView(view);
    }
    else if (view.viewType == "div" || view.viewType == "layout" || view.viewType == "menu") {
        touchMoveDiv(view, firstTouch, firstPoint, secondTouch, secondPoint);
        invalidateView(view);
    }
    else if (view.viewType == "chart") {
        touchMoveChart(view, firstTouch, firstPoint, secondTouch, secondPoint);
        invalidateView(view);
    }
    else if (view.viewType == "button") {
        invalidateView(view);
    }
    else if (view.viewType == "menuitem") {
        touchMoveMenuItem(view);
    }
    else {
        if (view.allowDrag && view.parent && view.parent.viewType == "split" && view.parent.splitter == view) {
            let splitLayoutDiv = view.parent;
            if (splitLayoutDiv.layoutStyle == "lefttoright" || splitLayoutDiv.layoutStyle == "righttoleft") {
                if (view.paint != null && view.paint.canvas) {
                    view.paint.canvas.style.cursor = "ew-resize";
                }
            }
            else {
                if (view.paint != null && view.paint.canvas) {
                    view.paint.canvas.style.cursor = "ns-resize";
                }
            }
        }
        invalidateView(view);
    }
}
/*
* 鼠标滚动实现方法
* view:视图
* mp:坐标
* button:按钮
* clicks:点击次数
* delta:滚轮值
*/
function onMouseWheelDefault(view, mp, buttons, clicks, delta) {
    if (view.onMouseWheel) {
        view.onMouseWheel(view, mp, buttons, clicks, delta);
        return;
    }
    if (view.viewType == "tree") {
        touchWheelTree(view, delta);
        invalidateView(view);
    }
    else if (view.viewType == "grid") {
        touchWheelGrid(view, delta);
        invalidateView(view);
    }
    else if (view.viewType == "div" || view.viewType == "layout" || view.viewType == "menu") {
        touchWheelDiv(view, delta);
        invalidateView(view);
    }
    else if (view.viewType == "chart") {
        if (delta < 0) {
            zoomOutChart(view);
        }
        else if (delta > 0) {
            zoomInChart(view);
        }
        invalidateView(view);
    }
}
/*
* 鼠标抬起实现方法
* view:视图
* mp:坐标
* button:按钮
* clicks:点击次数
* delta:滚轮值
*/
function onMouseUpDefault(view, mp, buttons, clicks, delta) {
    if (view.onMouseUp) {
        view.onMouseUp(view, mp, buttons, clicks, delta);
        return;
    }
    let firstTouch = false, secondTouch = false;
    let firstPoint = mp, secondPoint = mp;
    if (buttons == 1) {
        firstTouch = true;
    }
    else if (buttons == 2) {
        secondTouch = true;
    }
    if (view.viewType == "tree") {
        touchUpTree(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
    }
    else if (view.viewType == "grid") {
        touchUpGrid(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
    }
    else if (view.viewType == "div" || view.viewType == "layout" || view.viewType == "menu") {
        touchUpDiv(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
    }
    else if (view.viewType == "chart") {
        view.firstTouchIndexCacheChart = -1;
        view.secondTouchIndexCacheChart = -1;
    }
    invalidateView(view);
}
/*
* 键盘按下方法
* view:视图
* key:按键
*/
function onKeyDownDefault(view, key) {
    if (view.onKeyDown) {
        view.onKeyDown(view, key);
        return;
    }
    if (view.viewType == "chart") {
        keyDownChart(view, key);
        invalidateView(view);
    }
}
/*
* 键盘抬起方法
* view:视图
* key:按键
*/
function onKeyUpDefault(view, key) {
    if (view.onKeyUp) {
        view.onKeyUp(view, key);
        return;
    }
}
/*
 * 缩放Canvas
 */
function scaleCanvas(paint) {
    //缩放高清模式
    if (window.devicePixelRatio && !isMobileMode()) {
        let canvas = paint.canvas;
        canvas.style.width = canvas.width + 'px';
        canvas.style.height = canvas.height + 'px';
        canvas.height = canvas.height * window.devicePixelRatio;
        canvas.width = canvas.width * window.devicePixelRatio;
        let context = canvas.getContext("2d"); //绘图上下文
        if (context) {
            context.scale(window.devicePixelRatio, window.devicePixelRatio);
            paint.ratio = window.devicePixelRatio;
        }
    }
}
/*
* 显示输入框
* view:视图
* lastView:上次的视图
*/
function showTextInput(view, lastView) {
    let paint = view.paint;
    if (paint.textBox && paint.editingTextBox) {
        if (lastView && lastView != view && lastView.viewType == "textbox") {
            lastView.text = paint.textBox.value;
            invalidateView(lastView);
        }
    }
    if (!paint.textBox) {
        let input = document.createElement("input");
        paint.textBox = input;
        input.type = "text";
        input.style.position = "absolute";
        input.style.boxSizing = "border-box";
        document.body.appendChild(input);
    }
    paint.editingTextBox = view;
    if (view.font && view.paint) {
        let strs = view.font.split(',');
        let fontFamily = strs[0];
        if (fontFamily == "Default") {
            fontFamily = paint.systemFont;
        }
        let sFont = strs[1] + "px " + fontFamily;
        if (paint.scaleFactorX != 1 || paint.scaleFactorY != 1) {
            sFont = Math.min(paint.scaleFactorX, paint.scaleFactorY) * parseFloat(strs[1]) + "px " + fontFamily;
        }
        paint.textBox.style.font = sFont;
    }
    paint.textBox.style.backgroundColor = convertColor(view.backColor);
    paint.textBox.style.border = "1px solid " + convertColor(view.borderColor);
    paint.textBox.style.color = convertColor(view.textColor);
    paint.textBox.style.display = "block";
    paint.textBox.value = view.text;
    invalidateEdit(paint);
    focusingTextBox = paint.textBox;
}
let focusingTextBox = null;
/*
* 隐藏输入框
* view:视图
*/
function hideTextInput(view) {
    let paint = view.paint;
    if (paint.textBox && paint.editingTextBox) {
        paint.textBox.style.display = "none";
        paint.editingTextBox.text = paint.textBox.value;
        paint.textBox.style.left = "-100000px";
        paint.textBox.style.top = "-100000px";
        paint.editingTextBox = null;
        invalidate(paint);
    }
}